Skip to content

Read entries from packages_composer_packages table

What does this MR do and why?

This MR introduces the new class Packages::Composer::Package that is linked to packages_composer_packages table.

Also it changes the Packages::Composer::PackageFinder to use the new class when the feature flag is enabled. This way the Composer package managers will get the entries from the packages_composer_packages table.

We keep writing to the existing packages_packages table that contains database triggers to sync the data with packages_composer_packages table.

References

Read entries from packages_composer_packages table (#569886)

Screenshots or screen recordings

No.

Database analysis

Packages::Composer::PackageFinder#execute

postges.ai setup
exec CREATE INDEX idx_pkgs_composer_pkgs_on_name_target_sha_status_project_id ON packages_composer_packages (name, target_sha, status, project_id);

With project

Query
SELECT "packages_composer_packages".*
FROM "packages_composer_packages"
WHERE "packages_composer_packages"."project_id" = XXX
  AND "packages_composer_packages"."status" IN (0,
                                                1,
                                                5)
  AND "packages_composer_packages"."name" = 'XXX'
  AND "packages_composer_packages"."target_sha" = 'XXX';

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/42551/commands/130263

With group

Query
SELECT "packages_composer_packages".*
FROM "packages_composer_packages"
WHERE "packages_composer_packages"."project_id" IN
    (SELECT "projects"."id"
     FROM "projects"
     LEFT JOIN project_features ON projects.id = project_features.project_id
     WHERE "projects"."namespace_id" IN
         (SELECT "namespaces"."id"
          FROM UNNEST(COALESCE(
                                 (SELECT ids
                                  FROM
                                    (SELECT "namespace_descendants"."self_and_descendant_group_ids" AS ids
                                     FROM "namespace_descendants"
                                     WHERE "namespace_descendants"."outdated_at" IS NULL
                                       AND "namespace_descendants"."namespace_id" = XXX) cached_query),
                                 (SELECT ids
                                  FROM
                                    (SELECT ARRAY_AGG("namespaces"."id") AS ids
                                     FROM
                                       (SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
                                        FROM "namespaces"
                                        WHERE "namespaces"."type" = 'Group'
                                          AND (traversal_ids @> ('{XXX}'))) namespaces) consistent_query))) AS namespaces(id))
       AND (EXISTS
              (SELECT 1
               FROM "project_authorizations"
               WHERE "project_authorizations"."user_id" = XXX
                 AND (project_authorizations.project_id = projects.id)
                 AND (project_authorizations.access_level >= 10))
            OR projects.visibility_level IN (10,
                                             20))
       AND ("project_features"."package_registry_access_level" > 0
            OR "project_features"."package_registry_access_level" IS NULL))
  AND "packages_composer_packages"."status" IN (0,
                                                1,
                                                5)
  AND "packages_composer_packages"."name" = 'XXX'
  AND "packages_composer_packages"."target_sha" = 'XXX';

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/42551/commands/130266


Packages::Composer::Package#valid_composer_global_name

postges.ai setup
exec CREATE INDEX idx_pkgs_composer_pkgs_on_name_target_sha_status_project_id ON packages_composer_packages (name, target_sha, status, project_id);
Query
SELECT 1 AS one
FROM "packages_composer_packages"
WHERE "packages_composer_packages"."status" != 4
  AND "packages_composer_packages"."name" = 'XXX'
  AND "packages_composer_packages"."project_id" != 'XXX'
LIMIT 1;

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/43590/commands/133155

How to set up and validate locally

Publish Composer package

With the feature flag enabled Feature.enable(:packages_composer_read_from_detached_table).

  1. Create a project and composer.json to it:

    composer.json
    {
      "name": "user/madrid",
      "autoload": {
        "psr-4": {
            "User\\Madrid\\": "src/"
        }
      },
      "authors": [
        {
            "name": "User"
        }
      ],
      "require": {}
    }
  2. Add a tag. For example 1.0.0

  3. Publish a package

    $ curl --fail-with-body --data tag=<tag> "https://__token__:<personal-access-token>@gitlab.example.com/api/v4/projects/<project_id>/packages/composer"
  4. Verify that the package was successfully published.

  5. Install composer package docs

Repeat the same steps with the feature flag disabled Feature.enable(:packages_composer_read_from_detached_table) to make sure everything works properly in both cases.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #569886

Edited by Dzmitry (Dima) Meshcharakou

Merge request reports

Loading