164
internal/store/store.go
Normal file
164
internal/store/store.go
Normal file
@@ -0,0 +1,164 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user