Skip to content

Commit c660711

Browse files
committed
materialize release_build_status view for performance
1 parent 7048b2a commit c660711

12 files changed

+139
-20
lines changed

.sqlx/query-5ecd90db215d7bf3178869a320176af53e2e45f860edd6b2bb42ed5b45ae4efa.json renamed to .sqlx/query-0b4084390b6c738c6f26c2dd13eff6ec8e7ea47c4d005d6cc00dbc60f69380cf.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-e8f8c3649576bcba99393a2e78c9f892efba0a451bb14fff77876ca250b0fab1.json renamed to .sqlx/query-162c05df1f44bb48d087b6e6e4b3a8ab868b6d0cc20143b176522c0791a7023c.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-649f22aaffbd35cb00a820a68677797e8bbde159b10d04e3945520a61b63ecb0.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-2e8ab3494453908d26decae9f9f64741c42f9476ed8573511fe141883b86482d.json renamed to .sqlx/query-65f40f6603b1f3e736566c3d4e275bb47f6ebc389b0aa61f7732d1f354dc5259.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-7e833553cf419d8fbc3a5a0c504f0af2fa3d4aaca158c3b616f2e683a943bccb.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-b823051d59855fc332ad37ecbcd015344ee7f1d6add8cdeb3b71aee4dfd95eba.json renamed to .sqlx/query-a0253cf77dc601990a9b972f4efebae94787e8cf83c956638ee7d3ce7f137299.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
DROP TABLE release_build_status;
2+
3+
CREATE OR REPLACE VIEW release_build_status AS (
4+
SELECT
5+
summary.id,
6+
summary.last_build_time,
7+
CASE
8+
WHEN summary.success_count > 0 THEN 'success'::build_status
9+
WHEN summary.failure_count > 0 THEN 'failure'::build_status
10+
ELSE 'in_progress'::build_status
11+
END as build_status
12+
13+
FROM (
14+
SELECT
15+
r.id,
16+
MAX(b.build_time) as last_build_time,
17+
SUM(CASE WHEN b.build_status = 'success' THEN 1 ELSE 0 END) as success_count,
18+
SUM(CASE WHEN b.build_status = 'failure' THEN 1 ELSE 0 END) as failure_count
19+
FROM
20+
releases as r
21+
LEFT OUTER JOIN builds AS b on b.rid = r.id
22+
GROUP BY r.id
23+
) as summary
24+
);
25+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
DROP VIEW release_build_status;
2+
CREATE TABLE release_build_status (
3+
rid INTEGER NOT NULL PRIMARY KEY,
4+
last_build_time timestamp with time zone,
5+
build_status build_status NOT NULL
6+
);
7+
8+
9+
INSERT INTO release_build_status(rid, last_build_time, build_status)
10+
SELECT
11+
summary.id,
12+
summary.last_build_time,
13+
CASE
14+
WHEN summary.success_count > 0 THEN 'success'::build_status
15+
WHEN summary.failure_count > 0 THEN 'failure'::build_status
16+
ELSE 'in_progress'::build_status
17+
END as build_status
18+
19+
FROM (
20+
SELECT
21+
r.id,
22+
MAX(b.build_time) as last_build_time,
23+
SUM(CASE WHEN b.build_status = 'success' THEN 1 ELSE 0 END) as success_count,
24+
SUM(CASE WHEN b.build_status = 'failure' THEN 1 ELSE 0 END) as failure_count
25+
FROM
26+
releases as r
27+
LEFT OUTER JOIN builds AS b on b.rid = r.id
28+
GROUP BY r.id
29+
) as summary;
30+
31+
CREATE INDEX release_build_status_last_build_time_idx ON release_build_status USING btree (last_build_time DESC);
32+
CREATE INDEX release_build_status_build_status_idx ON release_build_status USING btree (build_status);

src/db/add_package.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ pub(crate) async fn add_package_into_database(
125125
.await
126126
.context("couldn't update latest version id")?;
127127

128+
update_build_status(conn, release_id).await?;
129+
128130
Ok(release_id)
129131
}
130132

@@ -144,6 +146,44 @@ pub async fn update_latest_version_id(conn: &mut sqlx::PgConnection, crate_id: i
144146
Ok(())
145147
}
146148

149+
pub async fn update_build_status(conn: &mut sqlx::PgConnection, release_id: i32) -> Result<()> {
150+
sqlx::query!(
151+
"INSERT INTO release_build_status(rid, last_build_time, build_status)
152+
SELECT
153+
summary.id,
154+
summary.last_build_time,
155+
CASE
156+
WHEN summary.success_count > 0 THEN 'success'::build_status
157+
WHEN summary.failure_count > 0 THEN 'failure'::build_status
158+
ELSE 'in_progress'::build_status
159+
END as build_status
160+
161+
FROM (
162+
SELECT
163+
r.id,
164+
MAX(b.build_time) as last_build_time,
165+
SUM(CASE WHEN b.build_status = 'success' THEN 1 ELSE 0 END) as success_count,
166+
SUM(CASE WHEN b.build_status = 'failure' THEN 1 ELSE 0 END) as failure_count
167+
FROM
168+
releases as r
169+
LEFT OUTER JOIN builds AS b on b.rid = r.id
170+
WHERE
171+
r.id = $1
172+
GROUP BY r.id
173+
) as summary
174+
175+
ON CONFLICT (rid) DO UPDATE
176+
SET
177+
last_build_time = EXCLUDED.last_build_time,
178+
build_status=EXCLUDED.build_status",
179+
release_id,
180+
)
181+
.execute(&mut *conn)
182+
.await?;
183+
184+
Ok(())
185+
}
186+
147187
async fn crate_id_from_release_id(conn: &mut sqlx::PgConnection, release_id: i32) -> Result<i32> {
148188
Ok(sqlx::query_scalar!(
149189
"SELECT crate_id
@@ -208,6 +248,8 @@ pub(crate) async fn add_build_into_database(
208248
.fetch_one(&mut *conn)
209249
.await?;
210250

251+
update_build_status(conn, release_id).await?;
252+
211253
let crate_id = crate_id_from_release_id(&mut *conn, release_id).await?;
212254
update_latest_version_id(&mut *conn, crate_id)
213255
.await

src/db/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub(crate) use self::add_package::{
77
add_build_into_database, add_doc_coverage, add_package_into_database,
88
};
99
pub use self::{
10-
add_package::update_crate_data_in_database,
10+
add_package::{update_build_status, update_crate_data_in_database},
1111
delete::{delete_crate, delete_version},
1212
file::{add_path_into_database, add_path_into_remote_archive},
1313
overrides::Overrides,

src/web/crate_details.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl CrateDetails {
190190
doc_coverage.total_items_needing_examples,
191191
doc_coverage.items_with_examples
192192
FROM releases
193-
INNER JOIN release_build_status ON releases.id = release_build_status.id
193+
INNER JOIN release_build_status ON releases.id = release_build_status.rid
194194
INNER JOIN crates ON releases.crate_id = crates.id
195195
LEFT JOIN doc_coverage ON doc_coverage.release_id = releases.id
196196
LEFT JOIN repositories ON releases.repository_id = repositories.id
@@ -380,7 +380,7 @@ pub(crate) async fn releases_for_crate(
380380
releases.rustdoc_status,
381381
releases.target_name
382382
FROM releases
383-
INNER JOIN release_build_status ON releases.id = release_build_status.id
383+
INNER JOIN release_build_status ON releases.id = release_build_status.rid
384384
WHERE
385385
releases.crate_id = $1"#,
386386
crate_id,
@@ -695,7 +695,10 @@ mod tests {
695695
assert_cache_control, assert_redirect, assert_redirect_cached, async_wrapper, wrapper,
696696
FakeBuild, TestDatabase, TestEnvironment,
697697
};
698-
use crate::{db::types::BuildStatus, registry_api::CrateOwner};
698+
use crate::{
699+
db::{types::BuildStatus, update_build_status},
700+
registry_api::CrateOwner,
701+
};
699702
use anyhow::Error;
700703
use kuchikiki::traits::TendrilSink;
701704
use reqwest::StatusCode;
@@ -712,7 +715,7 @@ mod tests {
712715
SELECT build_status as "build_status!: BuildStatus"
713716
FROM crates
714717
INNER JOIN releases ON crates.id = releases.crate_id
715-
INNER JOIN release_build_status ON releases.id = release_build_status.id
718+
INNER JOIN release_build_status ON releases.id = release_build_status.rid
716719
WHERE crates.name = $1 AND releases.version = $2"#,
717720
name,
718721
version
@@ -1800,7 +1803,8 @@ mod tests {
18001803
#[test]
18011804
fn test_build_status_no_builds() {
18021805
async_wrapper(|env| async move {
1803-
env.async_fake_release()
1806+
let release_id = env
1807+
.async_fake_release()
18041808
.await
18051809
.name("dummy")
18061810
.version("0.1.0")
@@ -1812,6 +1816,8 @@ mod tests {
18121816
.execute(&mut *conn)
18131817
.await?;
18141818

1819+
update_build_status(&mut conn, release_id).await?;
1820+
18151821
assert_eq!(
18161822
release_build_status(&mut conn, "dummy", "0.1.0").await,
18171823
BuildStatus::InProgress

0 commit comments

Comments
 (0)