From 1d552cc09bdfb68ab3f84268f68257b99c94a4c2 Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Wed, 5 Feb 2025 16:38:27 +0800 Subject: [PATCH] db: Add `default_versions.num_versions` column --- crates/crates_io_database/src/schema.rs | 2 ++ .../crates_io_database_dump/src/dump-db.toml | 1 + ...e_dump__tests__sql_scripts@export.sql.snap | 2 +- ...e_dump__tests__sql_scripts@import.sql.snap | 2 +- .../down.sql | 4 +++ .../up.sql | 27 +++++++++++++++++++ src/controllers/krate/publish.rs | 10 +------ src/tests/krate/publish/basics.rs | 19 +++++++++++++ 8 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 migrations/2025-02-05-083109_add-num-versions-column/down.sql create mode 100644 migrations/2025-02-05-083109_add-num-versions-column/up.sql diff --git a/crates/crates_io_database/src/schema.rs b/crates/crates_io_database/src/schema.rs index da1c15d20c5..099c4afc42d 100644 --- a/crates/crates_io_database/src/schema.rs +++ b/crates/crates_io_database/src/schema.rs @@ -408,6 +408,8 @@ diesel::table! { crate_id -> Int4, /// Reference to the version in the `versions` table. version_id -> Int4, + /// The total number of versions. + num_versions -> Nullable, } } diff --git a/crates/crates_io_database_dump/src/dump-db.toml b/crates/crates_io_database_dump/src/dump-db.toml index 90d3969cf5d..5a92c67baa1 100644 --- a/crates/crates_io_database_dump/src/dump-db.toml +++ b/crates/crates_io_database_dump/src/dump-db.toml @@ -105,6 +105,7 @@ dependencies = ["crates", "versions"] [default_versions.columns] crate_id = "public" version_id = "public" +num_versions = "public" [deleted_crates] dependencies = ["users"] diff --git a/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@export.sql.snap b/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@export.sql.snap index 02ace01abcb..1d801f192d7 100644 --- a/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@export.sql.snap +++ b/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@export.sql.snap @@ -18,7 +18,7 @@ BEGIN ISOLATION LEVEL REPEATABLE READ, READ ONLY; \copy (SELECT "crate_id", "created_at", "created_by", "owner_id", "owner_kind" FROM "crate_owners" WHERE NOT deleted) TO 'data/crate_owners.csv' WITH CSV HEADER \copy "versions" ("bin_names", "categories", "checksum", "crate_id", "crate_size", "created_at", "description", "documentation", "downloads", "edition", "features", "has_lib", "homepage", "id", "keywords", "license", "links", "num", "num_no_build", "published_by", "repository", "rust_version", "updated_at", "yanked") TO 'data/versions.csv' WITH CSV HEADER - \copy "default_versions" ("crate_id", "version_id") TO 'data/default_versions.csv' WITH CSV HEADER + \copy "default_versions" ("crate_id", "num_versions", "version_id") TO 'data/default_versions.csv' WITH CSV HEADER \copy "dependencies" ("crate_id", "default_features", "explicit_name", "features", "id", "kind", "optional", "req", "target", "version_id") TO 'data/dependencies.csv' WITH CSV HEADER \copy "version_downloads" ("date", "downloads", "version_id") TO 'data/version_downloads.csv' WITH CSV HEADER COMMIT; diff --git a/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@import.sql.snap b/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@import.sql.snap index 6747fba2923..f5315ad6929 100644 --- a/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@import.sql.snap +++ b/crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@import.sql.snap @@ -60,7 +60,7 @@ BEGIN; \copy "crates_keywords" ("crate_id", "keyword_id") FROM 'data/crates_keywords.csv' WITH CSV HEADER \copy "crate_owners" ("crate_id", "created_at", "created_by", "owner_id", "owner_kind") FROM 'data/crate_owners.csv' WITH CSV HEADER \copy "versions" ("bin_names", "categories", "checksum", "crate_id", "crate_size", "created_at", "description", "documentation", "downloads", "edition", "features", "has_lib", "homepage", "id", "keywords", "license", "links", "num", "num_no_build", "published_by", "repository", "rust_version", "updated_at", "yanked") FROM 'data/versions.csv' WITH CSV HEADER - \copy "default_versions" ("crate_id", "version_id") FROM 'data/default_versions.csv' WITH CSV HEADER + \copy "default_versions" ("crate_id", "num_versions", "version_id") FROM 'data/default_versions.csv' WITH CSV HEADER \copy "dependencies" ("crate_id", "default_features", "explicit_name", "features", "id", "kind", "optional", "req", "target", "version_id") FROM 'data/dependencies.csv' WITH CSV HEADER \copy "version_downloads" ("date", "downloads", "version_id") FROM 'data/version_downloads.csv' WITH CSV HEADER diff --git a/migrations/2025-02-05-083109_add-num-versions-column/down.sql b/migrations/2025-02-05-083109_add-num-versions-column/down.sql new file mode 100644 index 00000000000..c2fe6c3aa22 --- /dev/null +++ b/migrations/2025-02-05-083109_add-num-versions-column/down.sql @@ -0,0 +1,4 @@ +ALTER TABLE default_versions + DROP COLUMN num_versions; + +DROP FUNCTION IF EXISTS update_num_versions_from_versions CASCADE; diff --git a/migrations/2025-02-05-083109_add-num-versions-column/up.sql b/migrations/2025-02-05-083109_add-num-versions-column/up.sql new file mode 100644 index 00000000000..8f297121dab --- /dev/null +++ b/migrations/2025-02-05-083109_add-num-versions-column/up.sql @@ -0,0 +1,27 @@ +ALTER TABLE default_versions + ADD COLUMN num_versions INTEGER; + +COMMENT ON COLUMN default_versions.num_versions IS 'The total number of versions.'; + +CREATE OR REPLACE FUNCTION update_num_versions_from_versions() RETURNS TRIGGER AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO default_versions (crate_id, version_id, num_versions) + VALUES (NEW.crate_id, NEW.id, 1) + ON CONFLICT (crate_id) DO UPDATE + SET num_versions = EXCLUDED.num_versions + 1; + RETURN NEW; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE default_versions + SET num_versions = num_versions - 1 + WHERE crate_id = OLD.crate_id; + RETURN OLD; + END IF; +END +$$ LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS trigger_update_num_versions_from_versions ON versions; +CREATE TRIGGER trigger_update_num_versions_from_versions + AFTER INSERT OR DELETE ON versions + FOR EACH ROW + EXECUTE PROCEDURE update_num_versions_from_versions(); diff --git a/src/controllers/krate/publish.rs b/src/controllers/krate/publish.rs index c999e17a4c0..fac50ebc932 100644 --- a/src/controllers/krate/publish.rs +++ b/src/controllers/krate/publish.rs @@ -445,7 +445,7 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult AppResult>(&mut conn) + .await + .unwrap(); + assert_eq!(num_versions.len(), 1); + assert_eq!(num_versions[0], Some(1)); + let crate_to_publish = PublishBuilder::new("foo_twice", "0.99.0"); let response = token.publish_crate(crate_to_publish).await; assert_eq!(response.status(), StatusCode::OK); @@ -130,6 +141,14 @@ async fn new_krate_twice_alt() { ".crate.updated_at" => "[datetime]", }); + let num_versions = default_versions::table + .select(default_versions::num_versions) + .load::>(&mut conn) + .await + .unwrap(); + assert_eq!(num_versions.len(), 1); + assert_eq!(num_versions[0], Some(2)); + let crates = app.crates_from_index_head("foo_twice"); assert_json_snapshot!(crates);