From b105b2cce9c5a59d33299dff006a29059f863b47 Mon Sep 17 00:00:00 2001 From: healthjyk Date: Fri, 15 Mar 2024 17:00:46 +0800 Subject: [PATCH] style: make state storages more tidy --- pkg/engine/state/storages/mysql.go | 60 ++++++++++++++----------- pkg/engine/state/storages/mysql_test.go | 21 ++++----- pkg/engine/state/storages/oss.go | 6 +-- pkg/engine/state/storages/s3.go | 4 -- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/pkg/engine/state/storages/mysql.go b/pkg/engine/state/storages/mysql.go index 77e33121..dcc197c8 100644 --- a/pkg/engine/state/storages/mysql.go +++ b/pkg/engine/state/storages/mysql.go @@ -1,6 +1,8 @@ package storages import ( + "errors" + "gopkg.in/yaml.v3" "gorm.io/gorm" @@ -23,74 +25,80 @@ func NewMysqlStorage(db *gorm.DB, project, stack, workspace string) *MysqlStorag } func (s *MysqlStorage) Get() (*v1.State, error) { - stateDO, err := getState(s.db, s.project, s.stack, s.workspace) + stateDO, err := getStateFromMysql(s.db, s.project, s.stack, s.workspace) if err != nil { return nil, err } if stateDO == nil { return nil, nil } - return convertFromDO(stateDO) + return convertFromMysqlDO(stateDO) } func (s *MysqlStorage) Apply(state *v1.State) error { - exist, err := isStateExist(s.db, s.project, s.stack, s.workspace) + exist, err := checkStateExistenceInMysql(s.db, s.project, s.stack, s.workspace) if err != nil { return err } - stateDO, err := convertToDO(state) + stateDO, err := convertToMysqlDO(state) if err != nil { return err } if exist { - return updateState(s.db, stateDO) + return updateStateInMysql(s.db, stateDO) } else { - return createState(s.db, stateDO) + return createStateInMysql(s.db, stateDO) } } -// State is the data object stored in the mysql db. -type State struct { +// StateMysqlDO is the data object stored in the mysql db. +type StateMysqlDO struct { Project string Stack string Workspace string Content string } -func (s State) TableName() string { +func (s StateMysqlDO) TableName() string { return stateTable } -func getState(db *gorm.DB, project, stack, workspace string) (*State, error) { - q := &State{ +func getStateFromMysql(db *gorm.DB, project, stack, workspace string) (*StateMysqlDO, error) { + q := &StateMysqlDO{ Project: project, Stack: stack, Workspace: workspace, } - s := &State{} + s := &StateMysqlDO{} result := db.Where(q).First(s) - // if no record, return nil - if *s == (State{}) { - s = nil + // if no record, return nil state and nil error + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, nil } return s, result.Error } -func isStateExist(db *gorm.DB, project, stack, workspace string) (bool, error) { - s, err := getState(db, project, stack, workspace) - if err != nil { - return false, err +func checkStateExistenceInMysql(db *gorm.DB, project, stack, workspace string) (bool, error) { + q := &StateMysqlDO{ + Project: project, + Stack: stack, + Workspace: workspace, + } + s := &StateMysqlDO{} + result := db.Select("project").Where(q).First(s) + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return false, nil } - return s != nil, err + return result.Error == nil, result.Error } -func createState(db *gorm.DB, s *State) error { +func createStateInMysql(db *gorm.DB, s *StateMysqlDO) error { return db.Create(s).Error } -func updateState(db *gorm.DB, s *State) error { - q := &State{ +func updateStateInMysql(db *gorm.DB, s *StateMysqlDO) error { + q := &StateMysqlDO{ Project: s.Project, Stack: s.Stack, Workspace: s.Workspace, @@ -98,12 +106,12 @@ func updateState(db *gorm.DB, s *State) error { return db.Where(q).Updates(s).Error } -func convertToDO(state *v1.State) (*State, error) { +func convertToMysqlDO(state *v1.State) (*StateMysqlDO, error) { content, err := yaml.Marshal(state) if err != nil { return nil, err } - return &State{ + return &StateMysqlDO{ Project: state.Project, Stack: state.Stack, Workspace: state.Workspace, @@ -111,7 +119,7 @@ func convertToDO(state *v1.State) (*State, error) { }, nil } -func convertFromDO(s *State) (*v1.State, error) { +func convertFromMysqlDO(s *StateMysqlDO) (*v1.State, error) { state := &v1.State{} if err := yaml.Unmarshal([]byte(s.Content), state); err != nil { return nil, err diff --git a/pkg/engine/state/storages/mysql_test.go b/pkg/engine/state/storages/mysql_test.go index 95cd388d..de104681 100644 --- a/pkg/engine/state/storages/mysql_test.go +++ b/pkg/engine/state/storages/mysql_test.go @@ -10,8 +10,8 @@ import ( v1 "kusionstack.io/kusion/pkg/apis/core/v1" ) -func mockStateDO() *State { - return &State{ +func mockStateMysqlDO() *StateMysqlDO { + return &StateMysqlDO{ Project: "wordpress", Stack: "dev", Workspace: "dev", @@ -27,13 +27,13 @@ func TestMysqlStorage_Get(t *testing.T) { testcases := []struct { name string success bool - stateDO *State + stateDO *StateMysqlDO state *v1.State }{ { name: "get mysql state successfully", success: true, - stateDO: mockStateDO(), + stateDO: mockStateMysqlDO(), state: mockState(), }, { @@ -46,7 +46,7 @@ func TestMysqlStorage_Get(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { mockey.PatchConvey("mock mysql get", t, func() { - mockey.Mock(getState).Return(tc.stateDO, nil).Build() + mockey.Mock(getStateFromMysql).Return(tc.stateDO, nil).Build() state, err := mockMysqlStorage().Get() assert.Equal(t, tc.success, err == nil) assert.Equal(t, tc.state, state) @@ -59,13 +59,13 @@ func TestMysqlStorage_Apply(t *testing.T) { testcases := []struct { name string success bool - lastStateDO *State + lastStateDO *StateMysqlDO state *v1.State }{ { name: "update mysql state successfully", success: true, - lastStateDO: mockStateDO(), + lastStateDO: mockStateMysqlDO(), state: mockState(), }, { @@ -78,9 +78,10 @@ func TestMysqlStorage_Apply(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { mockey.PatchConvey("mock mysql create and update", t, func() { - mockey.Mock(getState).Return(tc.lastStateDO, nil).Build() - mockey.Mock(createState).Return(nil).Build() - mockey.Mock(updateState).Return(nil).Build() + mockey.Mock(getStateFromMysql).Return(tc.lastStateDO, nil).Build() + mockey.Mock(checkStateExistenceInMysql).Return(tc.lastStateDO != nil, nil).Build() + mockey.Mock(createStateInMysql).Return(nil).Build() + mockey.Mock(updateStateInMysql).Return(nil).Build() err := mockMysqlStorage().Apply(tc.state) assert.Equal(t, tc.success, err == nil) }) diff --git a/pkg/engine/state/storages/oss.go b/pkg/engine/state/storages/oss.go index bcd5f98d..e3d43993 100644 --- a/pkg/engine/state/storages/oss.go +++ b/pkg/engine/state/storages/oss.go @@ -65,9 +65,5 @@ func (s *OssStorage) Apply(state *v1.State) error { return err } - err = s.bucket.PutObject(s.key, bytes.NewReader(content)) - if err != nil { - return err - } - return nil + return s.bucket.PutObject(s.key, bytes.NewReader(content)) } diff --git a/pkg/engine/state/storages/s3.go b/pkg/engine/state/storages/s3.go index a3aa189a..03d7dd8f 100644 --- a/pkg/engine/state/storages/s3.go +++ b/pkg/engine/state/storages/s3.go @@ -35,14 +35,10 @@ func (s *S3Storage) Get() (*v1.State, error) { Key: &s.key, } output, err := s.s3.GetObject(input) - var notExist bool if err != nil { awsErr, ok := err.(awserr.Error) // if no kusion state file, return nil state if ok && awsErr.Code() == s3.ErrCodeNoSuchKey { - notExist = true - } - if notExist { return nil, nil } return nil, err