Files
ci/internal/store/store.go
2026-06-18 21:19:47 +08:00

165 lines
4.1 KiB
Go

package store
import (
"ci/internal/model"
"os"
"path/filepath"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
)
// Store wraps the database connection and provides data access methods.
type Store struct {
DB *gorm.DB
}
// New creates a new Store, initializes the database, and runs migrations.
func New(dataDir string) (*Store, error) {
if err := os.MkdirAll(dataDir, 0755); err != nil {
return nil, err
}
dbPath := filepath.Join(dataDir, "ci.db")
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
if err != nil {
return nil, err
}
if err := db.AutoMigrate(&model.Project{}, &model.BuildRecord{}, &model.DeployConfig{}, &model.DeployRecord{}); err != nil {
return nil, err
}
return &Store{DB: db}, nil
}
// --- Project CRUD ---
func (s *Store) CreateProject(p *model.Project) error {
return s.DB.Create(p).Error
}
func (s *Store) ListProjects() ([]model.Project, error) {
var projects []model.Project
err := s.DB.Order("created_at desc").Find(&projects).Error
return projects, err
}
func (s *Store) GetProject(id uint) (*model.Project, error) {
var p model.Project
err := s.DB.First(&p, id).Error
if err != nil {
return nil, err
}
return &p, nil
}
func (s *Store) UpdateProject(p *model.Project) error {
return s.DB.Save(p).Error
}
func (s *Store) DeleteProject(id uint) error {
return s.DB.Delete(&model.Project{}, id).Error
}
// --- BuildRecord CRUD ---
func (s *Store) CreateBuildRecord(r *model.BuildRecord) error {
return s.DB.Create(r).Error
}
func (s *Store) UpdateBuildRecord(r *model.BuildRecord) error {
return s.DB.Save(r).Error
}
func (s *Store) GetBuildRecord(id uint) (*model.BuildRecord, error) {
var r model.BuildRecord
err := s.DB.Preload("Project").First(&r, id).Error
if err != nil {
return nil, err
}
return &r, nil
}
func (s *Store) ListBuildRecords(projectID uint, limit int) ([]model.BuildRecord, error) {
var records []model.BuildRecord
if limit <= 0 {
limit = 20
}
err := s.DB.Where("project_id = ?", projectID).
Order("started_at desc").
Limit(limit).
Find(&records).Error
return records, err
}
// --- DeployConfig CRUD ---
// GetDeployConfig returns the deploy config for a project, or nil if not configured.
func (s *Store) GetDeployConfig(projectID uint) (*model.DeployConfig, error) {
var cfg model.DeployConfig
err := s.DB.Where("project_id = ?", projectID).First(&cfg).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil // not configured is not an error
}
return nil, err
}
return &cfg, nil
}
// UpsertDeployConfig creates or updates the deploy config for a project.
func (s *Store) UpsertDeployConfig(cfg *model.DeployConfig) error {
// Use FirstOrCreate + Assign to handle upsert
var existing model.DeployConfig
err := s.DB.Where("project_id = ?", cfg.ProjectID).First(&existing).Error
if err == nil {
// Update existing
cfg.ID = existing.ID
cfg.CreatedAt = existing.CreatedAt
return s.DB.Save(cfg).Error
}
// Create new
return s.DB.Create(cfg).Error
}
// DeleteDeployConfig removes the deploy config for a project.
func (s *Store) DeleteDeployConfig(projectID uint) error {
return s.DB.Where("project_id = ?", projectID).Delete(&model.DeployConfig{}).Error
}
// --- DeployRecord CRUD ---
// CreateDeployRecord creates a new deploy record.
func (s *Store) CreateDeployRecord(r *model.DeployRecord) error {
return s.DB.Create(r).Error
}
// UpdateDeployRecord updates an existing deploy record.
func (s *Store) UpdateDeployRecord(r *model.DeployRecord) error {
return s.DB.Save(r).Error
}
// GetDeployRecord returns a single deploy record by ID.
func (s *Store) GetDeployRecord(id uint) (*model.DeployRecord, error) {
var r model.DeployRecord
err := s.DB.Preload("Project").First(&r, id).Error
if err != nil {
return nil, err
}
return &r, nil
}
// ListDeployRecords returns deploy history for a project.
func (s *Store) ListDeployRecords(projectID uint, limit int) ([]model.DeployRecord, error) {
var records []model.DeployRecord
if limit <= 0 {
limit = 20
}
err := s.DB.Where("project_id = ?", projectID).
Order("started_at desc").
Limit(limit).
Find(&records).Error
return records, err
}