mirror of
https://github.com/harness/drone.git
synced 2025-05-05 15:32:56 +00:00
feat: [AH-1223]: Implement delete version for non oci package types (#3684)
* feat: [AH-1223]: fix failing go lint * feat: [AH-1223]: fix failing go lint * feat: [AH-1223]: file name change * feat: [AH-1223]: file name change * feat: [AH-1223]: fix go lint errors * feat: [AH-1223]: add RPM package type in switch case * feat: [AH-1223]: cascade delete download_stats and bandwidth_stats * feat: [AH-1223]: resolve PR comments * feat: [AH-1223]: resolve PR comments * feat: [AH-1223]: fix failing go lint checks * feat: [AH-1223]: add different switch case for delete based on package type * feat: [AH-1223]: Implement delete version for non oci package types
This commit is contained in:
parent
e3e0af68ce
commit
8b277e62d7
@ -0,0 +1,6 @@
|
||||
ALTER TABLE download_stats DROP CONSTRAINT IF EXISTS fk_artifacts_artifact_id;
|
||||
|
||||
ALTER TABLE download_stats
|
||||
ADD CONSTRAINT fk_artifacts_artifact_id
|
||||
FOREIGN KEY (download_stat_artifact_id)
|
||||
REFERENCES artifacts(artifact_id);
|
@ -0,0 +1,7 @@
|
||||
ALTER TABLE download_stats DROP CONSTRAINT IF EXISTS fk_artifacts_artifact_id;
|
||||
|
||||
ALTER TABLE download_stats
|
||||
ADD CONSTRAINT fk_artifacts_artifact_id
|
||||
FOREIGN KEY (download_stat_artifact_id)
|
||||
REFERENCES artifacts(artifact_id)
|
||||
ON DELETE CASCADE;
|
@ -0,0 +1,6 @@
|
||||
ALTER TABLE bandwidth_stats DROP CONSTRAINT IF EXISTS fk_images_image_id;
|
||||
|
||||
ALTER TABLE bandwidth_stats
|
||||
ADD CONSTRAINT fk_images_image_id
|
||||
FOREIGN KEY (bandwidth_stat_image_id)
|
||||
REFERENCES images(image_id);
|
@ -0,0 +1,7 @@
|
||||
ALTER TABLE bandwidth_stats DROP CONSTRAINT IF EXISTS fk_images_image_id;
|
||||
|
||||
ALTER TABLE bandwidth_stats
|
||||
ADD CONSTRAINT fk_images_image_id
|
||||
FOREIGN KEY (bandwidth_stat_image_id)
|
||||
REFERENCES images(image_id)
|
||||
ON DELETE CASCADE;
|
@ -0,0 +1,39 @@
|
||||
CREATE TABLE download_stats_new
|
||||
(
|
||||
download_stat_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
download_stat_artifact_id INTEGER NOT NULL
|
||||
CONSTRAINT fk_artifacts_artifact_id
|
||||
REFERENCES artifacts (artifact_id),
|
||||
download_stat_timestamp INTEGER NOT NULL,
|
||||
download_stat_created_at INTEGER NOT NULL,
|
||||
download_stat_updated_at INTEGER NOT NULL,
|
||||
download_stat_created_by INTEGER NOT NULL,
|
||||
download_stat_updated_by INTEGER NOT NULL
|
||||
);
|
||||
|
||||
DROP INDEX IF EXISTS download_stat_artifact_id;
|
||||
|
||||
CREATE INDEX download_stat_artifact_id ON download_stats_new(download_stat_artifact_id);
|
||||
|
||||
INSERT INTO download_stats_new (
|
||||
download_stat_id,
|
||||
download_stat_artifact_id,
|
||||
download_stat_timestamp,
|
||||
download_stat_created_at,
|
||||
download_stat_updated_at,
|
||||
download_stat_created_by,
|
||||
download_stat_updated_by
|
||||
)
|
||||
SELECT
|
||||
download_stat_id,
|
||||
download_stat_artifact_id,
|
||||
download_stat_timestamp,
|
||||
download_stat_created_at,
|
||||
download_stat_updated_at,
|
||||
download_stat_created_by,
|
||||
download_stat_updated_by
|
||||
FROM download_stats;
|
||||
|
||||
DROP TABLE download_stats;
|
||||
|
||||
ALTER TABLE download_stats_new RENAME TO download_stats;
|
@ -0,0 +1,39 @@
|
||||
CREATE TABLE download_stats_new
|
||||
(
|
||||
download_stat_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
download_stat_artifact_id INTEGER NOT NULL
|
||||
CONSTRAINT fk_artifacts_artifact_id
|
||||
REFERENCES artifacts (artifact_id) ON DELETE CASCADE,
|
||||
download_stat_timestamp INTEGER NOT NULL,
|
||||
download_stat_created_at INTEGER NOT NULL,
|
||||
download_stat_updated_at INTEGER NOT NULL,
|
||||
download_stat_created_by INTEGER NOT NULL,
|
||||
download_stat_updated_by INTEGER NOT NULL
|
||||
);
|
||||
|
||||
DROP INDEX IF EXISTS download_stat_artifact_id;
|
||||
|
||||
CREATE INDEX download_stat_artifact_id ON download_stats_new(download_stat_artifact_id);
|
||||
|
||||
INSERT INTO download_stats_new (
|
||||
download_stat_id,
|
||||
download_stat_artifact_id,
|
||||
download_stat_timestamp,
|
||||
download_stat_created_at,
|
||||
download_stat_updated_at,
|
||||
download_stat_created_by,
|
||||
download_stat_updated_by
|
||||
)
|
||||
SELECT
|
||||
download_stat_id,
|
||||
download_stat_artifact_id,
|
||||
download_stat_timestamp,
|
||||
download_stat_created_at,
|
||||
download_stat_updated_at,
|
||||
download_stat_created_by,
|
||||
download_stat_updated_by
|
||||
FROM download_stats;
|
||||
|
||||
DROP TABLE download_stats;
|
||||
|
||||
ALTER TABLE download_stats_new RENAME TO download_stats;
|
@ -0,0 +1,41 @@
|
||||
CREATE TABLE bandwidth_stats_new
|
||||
(
|
||||
bandwidth_stat_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bandwidth_stat_image_id INTEGER NOT NULL
|
||||
CONSTRAINT fk_images_image_id
|
||||
REFERENCES images(image_id),
|
||||
bandwidth_stat_timestamp INTEGER NOT NULL,
|
||||
bandwidth_stat_bytes INTEGER,
|
||||
bandwidth_stat_type TEXT NOT NULL,
|
||||
bandwidth_stat_created_at INTEGER NOT NULL,
|
||||
bandwidth_stat_updated_at INTEGER NOT NULL,
|
||||
bandwidth_stat_created_by INTEGER NOT NULL,
|
||||
bandwidth_stat_updated_by INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO bandwidth_stats_new (
|
||||
bandwidth_stat_id,
|
||||
bandwidth_stat_image_id,
|
||||
bandwidth_stat_timestamp,
|
||||
bandwidth_stat_bytes,
|
||||
bandwidth_stat_type,
|
||||
bandwidth_stat_created_at,
|
||||
bandwidth_stat_updated_at,
|
||||
bandwidth_stat_created_by,
|
||||
bandwidth_stat_updated_by
|
||||
)
|
||||
SELECT
|
||||
bandwidth_stat_id,
|
||||
bandwidth_stat_image_id,
|
||||
bandwidth_stat_timestamp,
|
||||
bandwidth_stat_bytes,
|
||||
bandwidth_stat_type,
|
||||
bandwidth_stat_created_at,
|
||||
bandwidth_stat_updated_at,
|
||||
bandwidth_stat_created_by,
|
||||
bandwidth_stat_updated_by
|
||||
FROM bandwidth_stats;
|
||||
|
||||
DROP TABLE bandwidth_stats;
|
||||
|
||||
ALTER TABLE bandwidth_stats_new RENAME TO bandwidth_stats;
|
@ -0,0 +1,41 @@
|
||||
CREATE TABLE bandwidth_stats_new
|
||||
(
|
||||
bandwidth_stat_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bandwidth_stat_image_id INTEGER NOT NULL
|
||||
CONSTRAINT fk_images_image_id
|
||||
REFERENCES images(image_id) ON DELETE CASCADE,
|
||||
bandwidth_stat_timestamp INTEGER NOT NULL,
|
||||
bandwidth_stat_bytes INTEGER,
|
||||
bandwidth_stat_type TEXT NOT NULL,
|
||||
bandwidth_stat_created_at INTEGER NOT NULL,
|
||||
bandwidth_stat_updated_at INTEGER NOT NULL,
|
||||
bandwidth_stat_created_by INTEGER NOT NULL,
|
||||
bandwidth_stat_updated_by INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO bandwidth_stats_new (
|
||||
bandwidth_stat_id,
|
||||
bandwidth_stat_image_id,
|
||||
bandwidth_stat_timestamp,
|
||||
bandwidth_stat_bytes,
|
||||
bandwidth_stat_type,
|
||||
bandwidth_stat_created_at,
|
||||
bandwidth_stat_updated_at,
|
||||
bandwidth_stat_created_by,
|
||||
bandwidth_stat_updated_by
|
||||
)
|
||||
SELECT
|
||||
bandwidth_stat_id,
|
||||
bandwidth_stat_image_id,
|
||||
bandwidth_stat_timestamp,
|
||||
bandwidth_stat_bytes,
|
||||
bandwidth_stat_type,
|
||||
bandwidth_stat_created_at,
|
||||
bandwidth_stat_updated_at,
|
||||
bandwidth_stat_created_by,
|
||||
bandwidth_stat_updated_by
|
||||
FROM bandwidth_stats;
|
||||
|
||||
DROP TABLE bandwidth_stats;
|
||||
|
||||
ALTER TABLE bandwidth_stats_new RENAME TO bandwidth_stats;
|
@ -16,12 +16,14 @@ package metadata
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
apiauth "github.com/harness/gitness/app/api/auth"
|
||||
"github.com/harness/gitness/app/api/request"
|
||||
"github.com/harness/gitness/audit"
|
||||
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
|
||||
"github.com/harness/gitness/registry/app/api/utils"
|
||||
"github.com/harness/gitness/registry/services/webhook"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
@ -66,29 +68,86 @@ func (c *APIController) DeleteArtifactVersion(ctx context.Context, r artifact.De
|
||||
}
|
||||
|
||||
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
|
||||
if len(repoEntity.Name) == 0 {
|
||||
if err != nil {
|
||||
//nolint:nilerr
|
||||
return artifact.DeleteArtifactVersion404JSONResponse{
|
||||
NotFoundJSONResponse: artifact.NotFoundJSONResponse(
|
||||
*GetErrorResponse(http.StatusNotFound, "registry doesn't exist with this key"),
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
artifactName := string(r.Artifact)
|
||||
versionName := string(r.Version)
|
||||
registryName := repoEntity.Name
|
||||
|
||||
image, err := c.ImageStore.GetByRepoAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier, artifactName)
|
||||
if err != nil {
|
||||
//nolint:nilerr
|
||||
return artifact.DeleteArtifactVersion404JSONResponse{
|
||||
NotFoundJSONResponse: artifact.NotFoundJSONResponse(
|
||||
*GetErrorResponse(http.StatusNotFound, "image doesn't exist with this key"),
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
_, err = c.ArtifactStore.GetByName(ctx, image.ID, versionName)
|
||||
if err != nil {
|
||||
//nolint:nilerr
|
||||
return artifact.DeleteArtifactVersion404JSONResponse{
|
||||
NotFoundJSONResponse: artifact.NotFoundJSONResponse(
|
||||
*GetErrorResponse(http.StatusNotFound, "version doesn't exist with this key"),
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
switch regInfo.PackageType {
|
||||
case artifact.PackageTypeDOCKER:
|
||||
err = c.deleteTag(ctx, regInfo, registryName, session.Principal, artifactName,
|
||||
versionName)
|
||||
case artifact.PackageTypeHELM:
|
||||
err = c.deleteTag(ctx, regInfo, registryName, session.Principal, artifactName,
|
||||
versionName)
|
||||
case artifact.PackageTypeNPM:
|
||||
err = c.deleteVersion(ctx, regInfo, artifactName, versionName)
|
||||
case artifact.PackageTypeMAVEN:
|
||||
err = c.deleteVersion(ctx, regInfo, artifactName, versionName)
|
||||
case artifact.PackageTypePYTHON:
|
||||
err = c.deleteVersion(ctx, regInfo, artifactName, versionName)
|
||||
case artifact.PackageTypeGENERIC:
|
||||
err = c.deleteVersion(ctx, regInfo, artifactName, versionName)
|
||||
case artifact.PackageTypeNUGET:
|
||||
err = fmt.Errorf("delete version not supported for nuget")
|
||||
case artifact.PackageTypeRPM:
|
||||
err = fmt.Errorf("delete version not supported for rpm")
|
||||
default:
|
||||
err = fmt.Errorf("unsupported package type: %s", regInfo.PackageType)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return throwDeleteArtifactVersion500Error(err), err
|
||||
}
|
||||
|
||||
err = c.deleteTagWithAudit(ctx, regInfo, repoEntity.Name, session.Principal, string(r.Artifact),
|
||||
string(r.Version))
|
||||
|
||||
if err != nil {
|
||||
return throwDeleteArtifactVersion500Error(err), err
|
||||
auditErr := c.AuditService.Log(
|
||||
ctx,
|
||||
session.Principal,
|
||||
audit.NewResource(audit.ResourceTypeRegistry, artifactName),
|
||||
audit.ActionDeleted,
|
||||
regInfo.ParentRef,
|
||||
audit.WithData("registry name", registryName),
|
||||
audit.WithData("artifact name", artifactName),
|
||||
audit.WithData("version name", versionName),
|
||||
)
|
||||
if auditErr != nil {
|
||||
log.Ctx(ctx).Warn().Msgf("failed to insert audit log for delete artifact operation: %s", auditErr)
|
||||
}
|
||||
|
||||
return artifact.DeleteArtifactVersion200JSONResponse{
|
||||
SuccessJSONResponse: artifact.SuccessJSONResponse(*GetSuccessResponse()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *APIController) deleteTagWithAudit(
|
||||
func (c *APIController) deleteTag(
|
||||
ctx context.Context, regInfo *RegistryRequestBaseInfo,
|
||||
registryName string, principal types.Principal, artifactName string, versionName string,
|
||||
) error {
|
||||
@ -105,22 +164,54 @@ func (c *APIController) deleteTagWithAudit(
|
||||
regInfo.PackageType, artifactName, c.URLProvider)
|
||||
c.ArtifactEventReporter.ArtifactDeleted(ctx, &payload)
|
||||
}
|
||||
auditErr := c.AuditService.Log(
|
||||
ctx,
|
||||
principal,
|
||||
audit.NewResource(audit.ResourceTypeRegistry, artifactName),
|
||||
audit.ActionDeleted,
|
||||
regInfo.ParentRef,
|
||||
audit.WithData("registry name", registryName),
|
||||
audit.WithData("artifact name", artifactName),
|
||||
audit.WithData("version name", versionName),
|
||||
)
|
||||
if auditErr != nil {
|
||||
log.Ctx(ctx).Warn().Msgf("failed to insert audit log for delete tag operation: %s", auditErr)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *APIController) deleteVersion(
|
||||
ctx context.Context,
|
||||
regInfo *RegistryRequestBaseInfo,
|
||||
artifactName string,
|
||||
versionName string,
|
||||
) error {
|
||||
// get the file path based on package type
|
||||
filePath, err := utils.GetFilePath(regInfo.PackageType, artifactName, versionName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get file path: %w", err)
|
||||
}
|
||||
|
||||
err = c.tx.WithTx(
|
||||
ctx,
|
||||
func(ctx context.Context) error {
|
||||
// delete nodes from nodes store
|
||||
err = c.fileManager.DeleteNode(ctx, regInfo.RegistryID, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete artifacts from artifacts store
|
||||
err = c.ArtifactStore.DeleteByVersionAndImageName(ctx, artifactName, versionName, regInfo.RegistryID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete version: %w", err)
|
||||
}
|
||||
|
||||
// delete image if no other artifacts linked
|
||||
err = c.ImageStore.DeleteByImageNameIfNoLinkedArtifacts(ctx, regInfo.RegistryID, artifactName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete image: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func throwDeleteArtifactVersion500Error(err error) artifact.DeleteArtifactVersion500JSONResponse {
|
||||
return artifact.DeleteArtifactVersion500JSONResponse{
|
||||
InternalServerErrorJSONResponse: artifact.InternalServerErrorJSONResponse(
|
||||
|
65
registry/app/api/utils/path_utils.go
Normal file
65
registry/app/api/utils/path_utils.go
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
|
||||
)
|
||||
|
||||
func GetMavenFilePath(imageName string, version string) string {
|
||||
artifactName := strings.ReplaceAll(imageName, ".", "/")
|
||||
artifactName = strings.ReplaceAll(artifactName, ":", "/")
|
||||
filePathPrefix := "/" + artifactName
|
||||
if version != "" {
|
||||
filePathPrefix += "/" + version
|
||||
}
|
||||
return filePathPrefix
|
||||
}
|
||||
|
||||
func GetGenericFilePath(imageName string, version string) string {
|
||||
filePathPrefix := "/" + imageName
|
||||
if version != "" {
|
||||
filePathPrefix += "/" + version
|
||||
}
|
||||
return filePathPrefix
|
||||
}
|
||||
|
||||
func GetFilePath(
|
||||
packageType artifact.PackageType,
|
||||
imageName string, version string) (string, error) {
|
||||
switch packageType {
|
||||
case artifact.PackageTypeDOCKER:
|
||||
return "", fmt.Errorf("docker package type not supported")
|
||||
case artifact.PackageTypeHELM:
|
||||
return "", fmt.Errorf("helm package type not supported")
|
||||
case artifact.PackageTypeNPM:
|
||||
return GetGenericFilePath(imageName, version), nil
|
||||
case artifact.PackageTypeMAVEN:
|
||||
return GetMavenFilePath(imageName, version), nil
|
||||
case artifact.PackageTypePYTHON:
|
||||
return GetGenericFilePath(imageName, version), nil
|
||||
case artifact.PackageTypeGENERIC:
|
||||
return GetGenericFilePath(imageName, version), nil
|
||||
case artifact.PackageTypeNUGET:
|
||||
return "", fmt.Errorf("nuget package type not supported")
|
||||
case artifact.PackageTypeRPM:
|
||||
return "", fmt.Errorf("rpm package type not supported")
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported package type: %s", packageType)
|
||||
}
|
||||
}
|
@ -255,12 +255,15 @@ func (f *FileManager) DownloadFile(
|
||||
return reader, blob.Size, "", nil
|
||||
}
|
||||
|
||||
func (f *FileManager) DeleteFile(
|
||||
func (f *FileManager) DeleteNode(
|
||||
ctx context.Context,
|
||||
regID int64,
|
||||
filePath string,
|
||||
regID int,
|
||||
) error {
|
||||
log.Ctx(ctx).Info().Msgf("%s%d", filePath, regID)
|
||||
err := f.nodesDao.DeleteByNodePathAndRegistryID(ctx, filePath, regID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete file for path: %s, with error: %w", filePath, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -441,6 +441,7 @@ type ImageRepository interface {
|
||||
DeleteDownloadStatByRegistryID(ctx context.Context, registryID int64) (err error)
|
||||
|
||||
DeleteByImageNameAndRegID(ctx context.Context, regID int64, image string) (err error)
|
||||
DeleteByImageNameIfNoLinkedArtifacts(ctx context.Context, regID int64, image string) (err error)
|
||||
}
|
||||
|
||||
type ArtifactRepository interface {
|
||||
|
@ -185,9 +185,17 @@ func (a ArtifactDao) Count(ctx context.Context) (int64, error) {
|
||||
}
|
||||
|
||||
func (a ArtifactDao) DeleteByImageNameAndRegistryID(ctx context.Context, regID int64, image string) (err error) {
|
||||
delStmt := databaseg.Builder.Delete("artifacts").
|
||||
Where("artifact_id IN (SELECT a.artifact_id FROM artifacts a JOIN images i ON i.image_id = a.artifact_image_id"+
|
||||
" WHERE i.image_name = ? AND i.image_registry_id = ?)", image, regID)
|
||||
var delStmt sq.DeleteBuilder
|
||||
switch a.db.DriverName() {
|
||||
case SQLITE3:
|
||||
delStmt = databaseg.Builder.Delete("artifacts").
|
||||
Where("artifact_id IN (SELECT a.artifact_id FROM artifacts a JOIN images i ON i.image_id = a.artifact_image_id"+
|
||||
" WHERE i.image_name = ? AND i.image_registry_id = ?)", image, regID)
|
||||
default:
|
||||
delStmt = databaseg.Builder.Delete("artifacts a USING images i").
|
||||
Where("a.artifact_image_id = i.image_id").
|
||||
Where("i.image_name = ? AND i.image_registry_id = ?", image, regID)
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, a.db)
|
||||
|
||||
@ -208,9 +216,18 @@ func (a ArtifactDao) DeleteByVersionAndImageName(
|
||||
ctx context.Context, image string,
|
||||
version string, regID int64,
|
||||
) (err error) {
|
||||
delStmt := databaseg.Builder.Delete("artifacts").
|
||||
Where("artifact_id IN (SELECT a.artifact_id FROM artifacts a JOIN images i ON i.image_id = a.artifact_image_id"+
|
||||
" WHERE a.artifact_name = ? AND i.image_name = ? AND i.image_registry_id = ?)", version, image, regID)
|
||||
var delStmt sq.DeleteBuilder
|
||||
switch a.db.DriverName() {
|
||||
case SQLITE3:
|
||||
delStmt = databaseg.Builder.Delete("artifacts").
|
||||
Where("artifact_id IN (SELECT a.artifact_id FROM artifacts a JOIN images i ON i.image_id = a.artifact_image_id"+
|
||||
" WHERE a.artifact_version = ? AND i.image_name = ? AND i.image_registry_id = ?)", version, image, regID)
|
||||
|
||||
default:
|
||||
delStmt = databaseg.Builder.Delete("artifacts a USING images i").
|
||||
Where("a.artifact_image_id = i.image_id").
|
||||
Where("a.artifact_version = ? AND i.image_name = ? AND i.image_registry_id = ?", version, image, regID)
|
||||
}
|
||||
|
||||
sql, args, err := delStmt.ToSql()
|
||||
if err != nil {
|
||||
|
@ -217,6 +217,28 @@ func (i ImageDao) DeleteDownloadStatByRegistryID(ctx context.Context, registryID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i ImageDao) DeleteByImageNameIfNoLinkedArtifacts(
|
||||
ctx context.Context, regID int64, image string,
|
||||
) error {
|
||||
stmt := databaseg.Builder.Delete("images").
|
||||
Where("image_name = ? AND image_registry_id = ?", image, regID).
|
||||
Where("NOT EXISTS ( SELECT 1 FROM artifacts WHERE artifacts.artifact_image_id = images.image_id )")
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to convert query to sql")
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, i.db)
|
||||
|
||||
_, err = db.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return databaseg.ProcessSQLErrorf(ctx, err, "the delete query failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i ImageDao) GetByName(ctx context.Context, registryID int64, name string) (*types.Image, error) {
|
||||
q := databaseg.Builder.Select(util.ArrToStringByDelimiter(util.GetDBTagsFromStruct(imageDB{}), ",")).
|
||||
From("images").
|
||||
|
Loading…
x
Reference in New Issue
Block a user