126 lines
3.3 KiB
Go
126 lines
3.3 KiB
Go
package models
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
cairnapi "github.com/mattnite/cairn/internal/api"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type CreateCampaignParams struct {
|
|
RepositoryID uint
|
|
Name string
|
|
Type string
|
|
Tags json.RawMessage
|
|
Metadata json.RawMessage
|
|
}
|
|
|
|
func CreateCampaign(ctx context.Context, db *gorm.DB, p CreateCampaignParams) (*cairnapi.Campaign, error) {
|
|
if p.Tags == nil {
|
|
p.Tags = json.RawMessage("{}")
|
|
}
|
|
if p.Metadata == nil {
|
|
p.Metadata = json.RawMessage("{}")
|
|
}
|
|
|
|
campaign := &Campaign{
|
|
RepositoryID: p.RepositoryID,
|
|
Name: p.Name,
|
|
Type: p.Type,
|
|
Status: "running",
|
|
StartedAt: time.Now(),
|
|
Tags: p.Tags,
|
|
Metadata: p.Metadata,
|
|
}
|
|
|
|
if err := db.WithContext(ctx).Create(campaign).Error; err != nil {
|
|
return nil, fmt.Errorf("creating campaign: %w", err)
|
|
}
|
|
return enrichCampaign(ctx, db, *campaign)
|
|
}
|
|
|
|
func FinishCampaign(ctx context.Context, db *gorm.DB, id uint) error {
|
|
now := time.Now()
|
|
if err := db.WithContext(ctx).Model(&Campaign{}).Where("id = ?", id).Updates(map[string]any{
|
|
"status": "finished",
|
|
"finished_at": now,
|
|
}).Error; err != nil {
|
|
return fmt.Errorf("finishing campaign: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func GetCampaign(ctx context.Context, db *gorm.DB, id uint) (*cairnapi.Campaign, error) {
|
|
campaign := &Campaign{}
|
|
if err := db.WithContext(ctx).First(campaign, id).Error; err != nil {
|
|
return nil, fmt.Errorf("getting campaign: %w", err)
|
|
}
|
|
return enrichCampaign(ctx, db, *campaign)
|
|
}
|
|
|
|
func ListCampaigns(ctx context.Context, db *gorm.DB, repoID *uint, limit, offset int) ([]cairnapi.Campaign, int64, error) {
|
|
if limit <= 0 {
|
|
limit = 50
|
|
}
|
|
|
|
query := db.WithContext(ctx).Model(&Campaign{})
|
|
if repoID != nil {
|
|
query = query.Where("repository_id = ?", *repoID)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("counting campaigns: %w", err)
|
|
}
|
|
|
|
var dbCampaigns []Campaign
|
|
if err := query.Order("created_at DESC").Limit(limit).Offset(offset).Find(&dbCampaigns).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("listing campaigns: %w", err)
|
|
}
|
|
|
|
campaigns := make([]cairnapi.Campaign, 0, len(dbCampaigns))
|
|
for _, m := range dbCampaigns {
|
|
c, err := enrichCampaign(ctx, db, m)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
campaigns = append(campaigns, *c)
|
|
}
|
|
|
|
return campaigns, total, nil
|
|
}
|
|
|
|
func enrichCampaign(ctx context.Context, db *gorm.DB, model Campaign) (*cairnapi.Campaign, error) {
|
|
repo := &Repository{}
|
|
if err := db.WithContext(ctx).First(repo, model.RepositoryID).Error; err != nil {
|
|
return nil, fmt.Errorf("loading campaign repository: %w", err)
|
|
}
|
|
|
|
var count int64
|
|
if err := db.WithContext(ctx).Model(&Artifact{}).Where("campaign_id = ?", model.ID).Count(&count).Error; err != nil {
|
|
return nil, fmt.Errorf("counting campaign artifacts: %w", err)
|
|
}
|
|
campaign := campaignFromModel(model)
|
|
campaign.RepoName = repo.Name
|
|
campaign.ArtifactCount = count
|
|
return &campaign, nil
|
|
}
|
|
|
|
func campaignFromModel(m Campaign) cairnapi.Campaign {
|
|
return cairnapi.Campaign{
|
|
ID: m.ID,
|
|
RepositoryID: m.RepositoryID,
|
|
Name: m.Name,
|
|
Type: m.Type,
|
|
Status: m.Status,
|
|
StartedAt: m.StartedAt,
|
|
FinishedAt: m.FinishedAt,
|
|
Tags: m.Tags,
|
|
Metadata: m.Metadata,
|
|
CreatedAt: m.CreatedAt,
|
|
}
|
|
}
|