chore: add archive column to template versions (#10178)

* chore: add archive column to template versions
This commit is contained in:
Steven Masley
2023-10-10 10:52:42 -05:00
committed by GitHub
parent c11f241622
commit 69d13f1676
15 changed files with 691 additions and 18 deletions
@@ -5,6 +5,13 @@ FROM
template_version_with_user AS template_versions
WHERE
template_id = @template_id :: uuid
AND CASE
-- If no filter is provided, default to returning ALL template versions.
-- The called should always provide a filter if they want to omit
-- archived versions.
WHEN sqlc.narg('archived') :: boolean IS NULL THEN true
ELSE template_versions.archived = sqlc.narg('archived') :: boolean
END
AND CASE
-- This allows using the last element on a page as effectively a cursor.
-- This is an important option for scripts that need to paginate without
@@ -129,3 +136,91 @@ WHERE
AND template_id = $3
ORDER BY created_at DESC
LIMIT 1;
-- name: UnarchiveTemplateVersion :exec
-- This will always work regardless of the current state of the template version.
UPDATE
template_versions
SET
archived = false,
updated_at = sqlc.arg('updated_at')
WHERE
id = sqlc.arg('template_version_id');
-- name: ArchiveUnusedTemplateVersions :many
-- Archiving templates is a soft delete action, so is reversible.
-- Archiving prevents the version from being used and discovered
-- by listing.
-- Only unused template versions will be archived, which are any versions not
-- referenced by the latest build of a workspace.
UPDATE
template_versions
SET
archived = true,
updated_at = sqlc.arg('updated_at')
FROM
-- Archive all versions that are returned from this query.
(
SELECT
scoped_template_versions.id
FROM
-- Scope an archive to a single template and ignore already archived template versions
(
SELECT
*
FROM
template_versions
WHERE
template_versions.template_id = sqlc.arg('template_id') :: uuid
AND
archived = false
AND
-- This allows archiving a specific template version.
CASE
WHEN sqlc.arg('template_version_id')::uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
template_versions.id = sqlc.arg('template_version_id') :: uuid
ELSE
true
END
) AS scoped_template_versions
LEFT JOIN
provisioner_jobs ON scoped_template_versions.job_id = provisioner_jobs.id
LEFT JOIN
templates ON scoped_template_versions.template_id = templates.id
WHERE
-- Actively used template versions (meaning the latest build is using
-- the version) are never archived. A "restart" command on the workspace,
-- even if failed, would use the version. So it cannot be archived until
-- the build is outdated.
NOT EXISTS (
-- Return all "used" versions, where "used" is defined as being
-- used by a latest workspace build.
SELECT template_version_id FROM (
SELECT
DISTINCT ON (workspace_id) template_version_id, transition
FROM
workspace_builds
ORDER BY workspace_id, build_number DESC
) AS used_versions
WHERE
used_versions.transition != 'delete'
AND
scoped_template_versions.id = used_versions.template_version_id
)
-- Also never archive the active template version
AND active_version_id != scoped_template_versions.id
AND CASE
-- Optionally, only archive versions that match a given
-- job status like 'failed'.
WHEN sqlc.narg('job_status') :: provisioner_job_status IS NOT NULL THEN
provisioner_jobs.job_status = sqlc.narg('job_status') :: provisioner_job_status
ELSE
true
END
-- Pending or running jobs should not be archived, as they are "in progress"
AND provisioner_jobs.job_status != 'running'
AND provisioner_jobs.job_status != 'pending'
) AS archived_versions
WHERE
template_versions.id IN (archived_versions.id)
RETURNING template_versions.id;