upda/server/repository_update.go
2024-04-20 19:10:17 +02:00

302 lines
7.1 KiB
Go

package server
import (
"encoding/json"
"git.myservermanager.com/varakh/upda/api"
"gorm.io/gorm"
"time"
)
type updateRepository interface {
paginate(page int, pageSize int, orderBy string, order string, searchTerm string, searchIn string, state ...api.UpdateState) ([]*Update, error)
count(searchTerm string, searchIn string, state ...api.UpdateState) (int64, error)
findAll() ([]*Update, error)
find(id string) (*Update, error)
findBy(application string, provider string, host string) (*Update, error)
create(application string, provider string, host string, version string, metadata interface{}) (*Update, error)
update(id string, version string, metadata interface{}) (*Update, error)
updateState(id string, state api.UpdateState) (*Update, error)
delete(id string) (int64, error)
deleteByUpdatedAtBeforeAndStates(time time.Time, state ...api.UpdateState) (int64, error)
}
type updateDbRepo struct {
db *gorm.DB
}
func newUpdateDbRepo(db *gorm.DB) *updateDbRepo {
return &updateDbRepo{
db: db,
}
}
func (r *updateDbRepo) findAll() ([]*Update, error) {
var e []*Update
var res *gorm.DB
if res = r.db.Find(&e); res.Error != nil {
return nil, newServiceDatabaseError(res.Error)
}
return e, nil
}
func (r *updateDbRepo) find(id string) (*Update, error) {
if id == "" {
return nil, errorValidationNotBlank
}
var e Update
var res *gorm.DB
if res = r.db.Find(&e, "id = ?", id); res.Error != nil {
return nil, newServiceDatabaseError(res.Error)
}
if res.RowsAffected == 0 {
return nil, errorResourceNotFound
}
return &e, nil
}
func (r *updateDbRepo) findBy(application string, provider string, host string) (*Update, error) {
if application == "" || provider == "" || host == "" {
return nil, errorValidationNotBlank
}
var e *Update
var res *gorm.DB
if res = r.db.Find(&e, &Update{Application: application, Provider: provider, Host: host}).Limit(1); res.Error != nil {
return nil, newServiceDatabaseError(res.Error)
}
if res.RowsAffected == 0 || e == nil {
return nil, errorResourceNotFound
}
return e, nil
}
func (r *updateDbRepo) create(application string, provider string, host string, version string, metadata interface{}) (*Update, error) {
if application == "" || provider == "" || host == "" || version == "" {
return nil, errorValidationNotBlank
}
var e *Update
unmarshalledMetadata := JSONMap{}
if metadata != nil {
marshalledMetadata, err := json.Marshal(metadata)
if err != nil {
return nil, err
}
err = unmarshalledMetadata.UnmarshalJSON(marshalledMetadata)
if err != nil {
return nil, err
}
}
e = &Update{
Application: application,
Provider: provider,
Host: host,
Version: version,
State: api.UpdateStatePending.Value(),
Metadata: unmarshalledMetadata,
}
var res *gorm.DB
if res = r.db.Create(&e); res.Error != nil {
return nil, newServiceDatabaseError(res.Error)
}
if res.RowsAffected == 0 {
return nil, errorDatabaseRowsExpected
}
return e, nil
}
func (r *updateDbRepo) updateState(id string, state api.UpdateState) (*Update, error) {
if id == "" || state == "" {
return nil, errorValidationNotBlank
}
var err error
var e *Update
if e, err = r.find(id); err != nil {
return nil, err
}
e.State = state.Value()
var res *gorm.DB
if res = r.db.Save(&e); res.Error != nil {
return nil, res.Error
}
if res.RowsAffected == 0 {
return e, errorDatabaseRowsExpected
}
return e, nil
}
func (r *updateDbRepo) update(id string, version string, metadata interface{}) (*Update, error) {
if id == "" || version == "" {
return nil, errorValidationNotBlank
}
var err error
var e *Update
if e, err = r.find(id); err != nil {
return nil, err
}
unmarshalledMetadata := JSONMap{}
if metadata != nil {
marshalledMetadata, err := json.Marshal(metadata)
if err != nil {
return nil, err
}
err = unmarshalledMetadata.UnmarshalJSON(marshalledMetadata)
if err != nil {
return nil, err
}
}
e.Version = version
e.Metadata = unmarshalledMetadata
var res *gorm.DB
if res = r.db.Save(&e); res.Error != nil {
return nil, res.Error
}
if res.RowsAffected == 0 {
return e, errorDatabaseRowsExpected
}
return e, nil
}
func (r *updateDbRepo) delete(id string) (int64, error) {
if id == "" {
return 0, errorValidationNotBlank
}
var res *gorm.DB
if res = r.db.Delete(&Update{}, "id = ?", id); res.Error != nil {
return 0, newServiceDatabaseError(res.Error)
}
return res.RowsAffected, nil
}
func (r *updateDbRepo) deleteByUpdatedAtBeforeAndStates(time time.Time, state ...api.UpdateState) (int64, error) {
if len(state) == 0 {
return 0, errorValidationNotEmpty
}
states := make([]string, 0)
for _, i := range state {
states = append(states, i.Value())
}
var res *gorm.DB
if res = r.db.Where("state IN ?", states).Where("updated_at < ?", time).Delete(&Update{}); res.Error != nil {
return 0, newServiceDatabaseError(res.Error)
}
return res.RowsAffected, nil
}
func (r *updateDbRepo) paginate(page int, pageSize int, orderBy string, order string, searchTerm string, searchIn string, state ...api.UpdateState) ([]*Update, error) {
if page == 0 {
return nil, errorValidationPageGreaterZero
}
if pageSize <= 0 {
return nil, errorValidationPageSizeGreaterZero
}
offset := (page - 1) * pageSize
var e []*Update
if orderBy == "" {
orderBy = "updated_at"
}
if order == "" {
order = "desc"
}
states := make([]string, 0)
if len(state) > 0 {
for _, s := range state {
states = append(states, s.Value())
}
}
if res := r.db.Scopes(allGetUpdateCriterion(searchTerm, searchIn, states)).Order(orderBy + " " + order).Offset(offset).Limit(pageSize).Find(&e); res.Error != nil {
return nil, newServiceDatabaseError(res.Error)
}
return e, nil
}
func (r *updateDbRepo) count(searchTerm string, searchIn string, state ...api.UpdateState) (int64, error) {
var c int64
states := make([]string, 0)
if len(state) > 0 {
for _, s := range state {
states = append(states, s.Value())
}
}
if res := r.db.Model(&Update{}).Scopes(allGetUpdateCriterion(searchTerm, searchIn, states)).Count(&c); res.Error != nil {
return 0, newServiceDatabaseError(res.Error)
}
return c, nil
}
func criterionUpdateSearch(searchTerm string, searchIn string) func(db *gorm.DB) *gorm.DB {
if searchTerm == "" || searchIn == "" {
return func(db *gorm.DB) *gorm.DB {
return db
}
}
switch searchIn {
case "host":
return func(db *gorm.DB) *gorm.DB {
return db.Where("host LIKE ?", "%"+searchTerm+"%")
}
case "provider":
return func(db *gorm.DB) *gorm.DB {
return db.Where("provider LIKE ?", "%"+searchTerm+"%")
}
default:
return func(db *gorm.DB) *gorm.DB {
return db.Where("application LIKE ?", "%"+searchTerm+"%")
}
}
}
func criterionUpdateState(states []string) func(db *gorm.DB) *gorm.DB {
if states != nil && len(states) > 0 {
return func(db *gorm.DB) *gorm.DB {
return db.Where("state IN (?)", states)
}
}
return func(db *gorm.DB) *gorm.DB {
return db
}
}
func allGetUpdateCriterion(searchTerm string, searchIn string, states []string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Scopes(criterionUpdateSearch(searchTerm, searchIn), criterionUpdateState(states))
}
}