horizoncd/horizon

View on GitHub
pkg/environment/dao/dao.go

Summary

Maintainability
C
1 day
Test Coverage
// Copyright © 2023 Horizoncd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dao

import (
    "context"
    "sort"

    herrors "github.com/horizoncd/horizon/core/errors"
    appregionmodels "github.com/horizoncd/horizon/pkg/applicationregion/models"
    "github.com/horizoncd/horizon/pkg/common"
    "github.com/horizoncd/horizon/pkg/environment/models"
    envregionmodels "github.com/horizoncd/horizon/pkg/environmentregion/models"
    "gorm.io/gorm"
)

type DAO interface {
    // CreateEnvironment create a environment
    CreateEnvironment(ctx context.Context, environment *models.Environment) (*models.Environment, error)
    // ListAllEnvironment list all environments
    ListAllEnvironment(ctx context.Context) ([]*models.Environment, error)
    // UpdateByID update environment by id
    UpdateByID(ctx context.Context, id uint, environment *models.Environment) error
    // DeleteByID delete environment by id
    DeleteByID(ctx context.Context, id uint) error
    // GetByID get environment by id
    GetByID(ctx context.Context, id uint) (*models.Environment, error)
    // GetByName get environment by name
    GetByName(ctx context.Context, name string) (*models.Environment, error)
}

type dao struct{ db *gorm.DB }

// NewDAO returns an instance of the default DAO
func NewDAO(db *gorm.DB) DAO {
    return &dao{db: db}
}

func (d *dao) UpdateByID(ctx context.Context, id uint, environment *models.Environment) error {
    environmentInDB, err := d.GetByID(ctx, id)
    if err != nil {
        return err
    }

    // set displayName and autoFree
    environmentInDB.DisplayName = environment.DisplayName
    res := d.db.WithContext(ctx).Save(&environmentInDB)
    if res.Error != nil {
        return herrors.NewErrUpdateFailed(herrors.EnvironmentInDB, res.Error.Error())
    }

    return nil
}

func (d *dao) CreateEnvironment(ctx context.Context, environment *models.Environment) (*models.Environment, error) {
    result := d.db.WithContext(ctx).Create(environment)

    if result.Error != nil {
        return nil, herrors.NewErrInsertFailed(herrors.EnvironmentRegionInDB, result.Error.Error())
    }

    return environment, result.Error
}

func (d *dao) ListAllEnvironment(ctx context.Context) ([]*models.Environment, error) {
    var environments []*models.Environment

    result := d.db.WithContext(ctx).Raw(common.EnvironmentListAll).Scan(&environments)

    if result.Error != nil {
        return nil, herrors.NewErrGetFailed(herrors.EnvironmentRegionInDB, result.Error.Error())
    }

    sort.Sort(models.EnvironmentList(environments))
    return environments, nil
}

func (d *dao) DeleteByID(ctx context.Context, id uint) error {
    environment, err := d.GetByID(ctx, id)
    if err != nil {
        return err
    }

    // remove related resources from different tables
    err = d.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
        // remove records from applicationRegion table
        res := tx.Where("environment_name = ?", environment.Name).Delete(&appregionmodels.ApplicationRegion{})
        if res.Error != nil {
            return herrors.NewErrDeleteFailed(herrors.RegionInDB, res.Error.Error())
        }

        // remove records from environmentRegion table
        res = tx.Where("environment_name = ?", environment.Name).Delete(&envregionmodels.EnvironmentRegion{})
        if res.Error != nil {
            return herrors.NewErrDeleteFailed(herrors.RegionInDB, res.Error.Error())
        }

        // remove environment itself
        res = tx.Delete(&models.Environment{}, id)
        if res.Error != nil {
            return herrors.NewErrDeleteFailed(herrors.EnvironmentInDB, res.Error.Error())
        }
        return nil
    })

    return err
}

func (d *dao) GetByID(ctx context.Context, id uint) (*models.Environment, error) {
    var environment models.Environment
    result := d.db.WithContext(ctx).Raw(common.EnvironmentGetByID, id).First(&environment)

    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return nil, herrors.NewErrNotFound(herrors.EnvironmentInDB, result.Error.Error())
        }
        return nil, herrors.NewErrGetFailed(herrors.EnvironmentInDB, result.Error.Error())
    }

    return &environment, nil
}

func (d *dao) GetByName(ctx context.Context, name string) (*models.Environment, error) {
    var environment models.Environment
    result := d.db.WithContext(ctx).Raw(common.EnvironmentGetByName, name).First(&environment)

    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return nil, herrors.NewErrNotFound(herrors.EnvironmentInDB, result.Error.Error())
        }
        return nil, herrors.NewErrGetFailed(herrors.EnvironmentInDB, result.Error.Error())
    }

    return &environment, nil
}