brunel/db/repository.go

201 lines
4.8 KiB
Go

package db
import (
"brunel/domain"
"time"
"github.com/alphadose/haxmap"
"github.com/jinzhu/now"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
const MaxBatchSize = 1999
type Repository struct {
db *gorm.DB
}
func NewRepository(db *gorm.DB) *Repository {
return &Repository{db: db}
}
func (r *Repository) GetUser(username string) (domain.User, error) {
var user domain.User
tx := r.db.Where("username = ?", username).First(&user)
return user, tx.Error
}
func (r *Repository) CreateUser(user domain.User) error {
tx := r.db.Create(&user)
return tx.Error
}
func (r *Repository) UpdateUser(user domain.User) error {
tx := r.db.Save(&user)
return tx.Error
}
func (r *Repository) CreateSession(session domain.Session) error {
tx := r.db.Create(&session)
return tx.Error
}
func (r *Repository) GetSession(token string) (domain.Session, error) {
now := now.BeginningOfMinute()
var session domain.Session
tx := r.db.Where("token = ? AND expiry > ?", token, now).First(&session)
return session, tx.Error
}
func (r *Repository) DeleteSession(token string) error {
tx := r.db.Delete(&domain.Session{}, "token = ?", token)
return tx.Error
}
func (r *Repository) DeleteExpiredSessions() error {
now := now.BeginningOfMinute()
tx := r.db.Where("expiry < ?", now).Delete(&domain.Session{})
return tx.Error
}
func (r *Repository) UpdatePackage(pkg domain.SourcePackage) error {
dto := sourcePackageToDto(pkg)
tx := r.db.Save(&dto)
return tx.Error
}
func (r *Repository) GetPackages() ([]domain.SourcePackage, error) {
var allPackages []domain.SourcePackage
offset := 0
for {
var batchPackages []domain.SourcePackageDTO
tx := r.db.Preload(clause.Associations).
Offset(offset).
Limit(MaxBatchSize).
Find(&batchPackages)
if tx.Error != nil {
return nil, tx.Error
}
// Convert DTOs to domain objects
for _, v := range batchPackages {
allPackages = append(allPackages, sourcePackageDtoToDomain(v))
}
// If we've retrieved fewer records than MaxBatchSize, we're done
if len(batchPackages) < MaxBatchSize {
break
}
// Move to the next batch
offset += MaxBatchSize
}
return allPackages, nil
}
func (r *Repository) GetPackage(name string) (domain.SourcePackage, error) {
var pkg domain.SourcePackageDTO
tx := r.db.Where("name = ?", name).First(&pkg)
if tx.Error != nil {
return domain.SourcePackage{}, tx.Error
}
return sourcePackageDtoToDomain(pkg), nil
}
func (r *Repository) SavePackages(pkgs *haxmap.Map[string, domain.SourcePackage]) error {
packs := make([]domain.SourcePackageDTO, 0)
pkgs.ForEach(func(k string, v domain.SourcePackage) bool {
packs = append(packs, sourcePackageToDto(v))
return true
})
for i := 0; i < len(packs); i += MaxBatchSize {
end := i + MaxBatchSize
length := len(packs)
if end > length {
end = length
}
tx := r.db.Save(packs[i:end])
if tx.Error != nil {
return tx.Error
}
}
return nil
}
func (r *Repository) DropPackages() error {
tx := r.db.Where("1 = 1").Delete(&domain.SourcePackageDTO{})
if tx.Error != nil {
return tx.Error
}
tx = r.db.Where("1 = 1").Delete(&domain.PackageInfo{})
return tx.Error
}
func (r *Repository) UpdateLastUpdateTime(time time.Time) error {
val := &domain.TimeContainer{
Time: time,
ID: "lastupdatetime",
}
tx := r.db.Save(val)
return tx.Error
}
func (r *Repository) UpdateBuildState(state domain.BuildState) error {
tx := r.db.Save(&state)
return tx.Error
}
func (r *Repository) GetBuildState(name string) (domain.BuildState, error) {
var state domain.BuildState
tx := r.db.Where("name = ?", name).First(&state)
return state, tx.Error
}
func (r *Repository) GetFailedBuilds() ([]domain.BuildState, error) {
var states []domain.BuildState
tx := r.db.Where("status = ? AND build_number > 1", string(domain.Error)).Find(&states)
return states, tx.Error
}
func sourcePackageToDto(pkg domain.SourcePackage) domain.SourcePackageDTO {
dto := domain.SourcePackageDTO{
Name: pkg.Name,
Version: pkg.Version,
NewVersion: pkg.NewVersion,
Status: pkg.Status,
LastBuildStatus: pkg.LastBuildStatus,
BuildAttempts: pkg.BuildAttempts,
Has32bit: pkg.Has32bit,
Packages: make([]domain.PackageInfo, 0),
}
pkg.Packages.ForEach(func(k string, v domain.PackageInfo) bool {
dto.Packages = append(dto.Packages, v)
return true
})
return dto
}
func sourcePackageDtoToDomain(dto domain.SourcePackageDTO) domain.SourcePackage {
pkg := domain.SourcePackage{
Name: dto.Name,
Version: dto.Version,
NewVersion: dto.NewVersion,
Status: dto.Status,
LastBuildStatus: dto.LastBuildStatus,
BuildAttempts: dto.BuildAttempts,
Has32bit: dto.Has32bit,
Packages: haxmap.New[string, domain.PackageInfo](),
}
for _, v := range dto.Packages {
pkg.Packages.Set(v.PackageName, v)
}
return pkg
}