harbor/src/pkg/scan/dao/scan/report.go

127 lines
3.5 KiB
Go

// Copyright Project Harbor Authors
//
// 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 scan
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/lib/q"
)
func init() {
orm.RegisterModel(new(Report))
}
// DAO is the data access object interface for report
type DAO interface {
// Create creates new report
Create(ctx context.Context, r *Report) (int64, error)
// Delete the reports according to the query
DeleteMany(ctx context.Context, query q.Query) (int64, error)
// List lists the reports with given query parameters.
List(ctx context.Context, query *q.Query) ([]*Report, error)
// UpdateReportData only updates the `report` column with conditions matched.
UpdateReportData(ctx context.Context, uuid string, report string) error
// Update update report
Update(ctx context.Context, r *Report, cols ...string) error
// DeleteByExtraAttr delete the scan_report by mimeType and extra attribute
DeleteByExtraAttr(ctx context.Context, mimeType, attrName, attrValue string) error
}
// New returns an instance of the default DAO
func New() DAO {
return &dao{}
}
type dao struct{}
// Create creates new report
func (d *dao) Create(ctx context.Context, r *Report) (int64, error) {
o, err := orm.FromContext(ctx)
if err != nil {
return 0, orm.WrapConflictError(err, "a previous scan report found for artifact %s", r.Digest)
}
return o.Insert(r)
}
func (d *dao) DeleteMany(ctx context.Context, query q.Query) (int64, error) {
if len(query.Keywords) == 0 {
return 0, errors.New("delete all reports at once is not allowed")
}
qs, err := orm.QuerySetter(ctx, &Report{}, &query)
if err != nil {
return 0, err
}
return qs.Delete()
}
func (d *dao) List(ctx context.Context, query *q.Query) ([]*Report, error) {
qs, err := orm.QuerySetter(ctx, &Report{}, query)
if err != nil {
return nil, err
}
reports := []*Report{}
if _, err = qs.All(&reports); err != nil {
return nil, err
}
return reports, nil
}
// UpdateReportData only updates the `report` column with conditions matched.
func (d *dao) UpdateReportData(ctx context.Context, uuid string, report string) error {
o, err := orm.FromContext(ctx)
if err != nil {
return err
}
qt := o.QueryTable(new(Report))
data := make(orm.Params)
data["report"] = report
_, err = qt.Filter("uuid", uuid).Update(data)
return err
}
func (d *dao) Update(ctx context.Context, r *Report, cols ...string) error {
o, err := orm.FromContext(ctx)
if err != nil {
return err
}
if _, err := o.Update(r, cols...); err != nil {
return err
}
return nil
}
func (d *dao) DeleteByExtraAttr(ctx context.Context, mimeType, attrName, attrValue string) error {
o, err := orm.FromContext(ctx)
if err != nil {
return err
}
delReportSQL := "delete from scan_report where mime_type = ? and report::jsonb @> ?"
dgstJSONStr := fmt.Sprintf(`{"%s":"%s"}`, attrName, attrValue)
_, err = o.Raw(delReportSQL, mimeType, dgstJSONStr).Exec()
return err
}