github.com/polarismesh/polaris@v1.17.8/store/boltdb/config_file_release_history.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package boltdb 19 20 import ( 21 "sort" 22 "strconv" 23 "strings" 24 "time" 25 26 bolt "go.etcd.io/bbolt" 27 "go.uber.org/zap" 28 29 "github.com/polarismesh/polaris/common/model" 30 "github.com/polarismesh/polaris/store" 31 ) 32 33 const ( 34 tblConfigFileReleaseHistory string = "ConfigFileReleaseHistory" 35 36 FileHistoryFieldId string = "Id" 37 FileHistoryFieldName string = "Name" 38 FileHistoryFieldNamespace string = "Namespace" 39 FileHistoryFieldGroup string = "Group" 40 FileHistoryFieldFileName string = "FileName" 41 FileHistoryFieldFormat string = "Format" 42 FileHistoryFieldTags string = "Tags" 43 FileHistoryFieldContent string = "Content" 44 FileHistoryFieldComment string = "Comment" 45 FileHistoryFieldMd5 string = "Md5" 46 FileHistoryFieldType string = "Type" 47 FileHistoryFieldStatus string = "Status" 48 FileHistoryFieldCreateBy string = "CreateBy" 49 FileHistoryFieldModifyBy string = "ModifyBy" 50 FileHistoryFieldCreateTime string = "CreateTime" 51 FileHistoryFieldModifyTime string = "ModifyTime" 52 FileHistoryFieldValid string = "Valid" 53 ) 54 55 type configFileReleaseHistoryStore struct { 56 handler BoltHandler 57 } 58 59 func newConfigFileReleaseHistoryStore(handler BoltHandler) *configFileReleaseHistoryStore { 60 s := &configFileReleaseHistoryStore{handler: handler} 61 return s 62 } 63 64 // CreateConfigFileReleaseHistory 创建配置文件发布历史记录 65 func (rh *configFileReleaseHistoryStore) CreateConfigFileReleaseHistory( 66 history *model.ConfigFileReleaseHistory) error { 67 68 err := rh.handler.Execute(true, func(tx *bolt.Tx) error { 69 table, err := tx.CreateBucketIfNotExists([]byte(tblConfigFileReleaseHistory)) 70 if err != nil { 71 return err 72 } 73 nextId, err := table.NextSequence() 74 if err != nil { 75 return err 76 } 77 78 history.Id = nextId 79 key := strconv.FormatUint(history.Id, 10) 80 history.Valid = true 81 history.CreateTime = time.Now() 82 history.ModifyTime = history.CreateTime 83 84 if err := saveValue(tx, tblConfigFileReleaseHistory, key, history); err != nil { 85 log.Error("[ConfigFileReleaseHistory] save info", zap.Error(err)) 86 return err 87 } 88 return nil 89 }) 90 91 return store.Error(err) 92 } 93 94 // QueryConfigFileReleaseHistories 获取配置文件的发布历史记录 95 func (rh *configFileReleaseHistoryStore) QueryConfigFileReleaseHistories(filter map[string]string, 96 offset, limit uint32) (uint32, []*model.ConfigFileReleaseHistory, error) { 97 98 var ( 99 namespace = filter["namespace"] 100 group = filter["group"] 101 fileName = filter["name"] 102 endId, _ = strconv.ParseUint(filter["endId"], 10, 64) 103 fields = []string{FileHistoryFieldNamespace, FileHistoryFieldGroup, 104 FileHistoryFieldFileName, FileHistoryFieldId} 105 hasNs = len(namespace) > 0 106 hasEndId = endId > 0 107 ) 108 109 ret, err := rh.handler.LoadValuesByFilter(tblConfigFileReleaseHistory, fields, 110 &model.ConfigFileReleaseHistory{}, func(m map[string]interface{}) bool { 111 saveNs, _ := m[FileHistoryFieldNamespace].(string) 112 saveFileGroup, _ := m[FileHistoryFieldGroup].(string) 113 saveFileName, _ := m[FileHistoryFieldFileName].(string) 114 saveID, _ := m[FileHistoryFieldId].(uint64) 115 116 if hasNs && strings.Compare(namespace, saveNs) != 0 { 117 return false 118 } 119 120 if hasEndId && endId <= uint64(saveID) { 121 return false 122 } 123 124 ret := strings.Contains(saveFileGroup, group) && strings.Contains(saveFileName, fileName) 125 return ret 126 }) 127 128 if err != nil { 129 return 0, nil, err 130 } 131 132 return uint32(len(ret)), doConfigFileHistoryPage(ret, offset, limit), nil 133 } 134 135 // GetLatestConfigFileReleaseHistory 获取最后一次发布记录 136 func (rh *configFileReleaseHistoryStore) GetLatestConfigFileReleaseHistory(namespace, group, 137 fileName string) (*model.ConfigFileReleaseHistory, error) { 138 fields := []string{FileHistoryFieldNamespace, FileHistoryFieldGroup, FileHistoryFieldFileName} 139 ret, err := rh.handler.LoadValuesByFilter(tblConfigFileReleaseHistory, fields, 140 &model.ConfigFileReleaseHistory{}, func(m map[string]interface{}) bool { 141 saveNs, _ := m[FileHistoryFieldNamespace].(string) 142 saveFileGroup, _ := m[FileHistoryFieldGroup].(string) 143 saveFileName, _ := m[FileHistoryFieldFileName].(string) 144 145 equalNs := strings.Compare(saveNs, namespace) == 0 146 equalGroup := strings.Compare(saveFileGroup, group) == 0 147 equalName := strings.Compare(saveFileName, fileName) == 0 148 return equalNs && equalGroup && equalName 149 }) 150 151 if err != nil { 152 return nil, err 153 } 154 155 if len(ret) == 0 { 156 return nil, nil 157 } 158 159 histories := make([]*model.ConfigFileReleaseHistory, 0, len(ret)) 160 for k := range ret { 161 histories = append(histories, ret[k].(*model.ConfigFileReleaseHistory)) 162 } 163 164 sort.Slice(histories, func(i, j int) bool { 165 return histories[i].Id > histories[j].Id 166 }) 167 168 return histories[0], nil 169 } 170 171 func (rh *configFileReleaseHistoryStore) CleanConfigFileReleaseHistory(endTime time.Time, limit uint64) error { 172 173 fields := []string{FileHistoryFieldCreateTime, FileHistoryFieldId} 174 needDel := make([]string, 0, limit) 175 176 _, err := rh.handler.LoadValuesByFilter(tblConfigFileReleaseHistory, fields, 177 &model.ConfigFileReleaseHistory{}, func(m map[string]interface{}) bool { 178 saveCreateBy, _ := m[FileHistoryFieldCreateTime].(time.Time) 179 saveId := m[FileHistoryFieldId].(uint64) 180 181 if endTime.After(saveCreateBy) { 182 needDel = append(needDel, strconv.FormatUint(saveId, 10)) 183 } 184 return false 185 }) 186 if err != nil { 187 return err 188 } 189 190 return rh.handler.DeleteValues(tblConfigFileReleaseHistory, needDel) 191 } 192 193 // doConfigFileGroupPage 进行分页 194 func doConfigFileHistoryPage(ret map[string]interface{}, offset, limit uint32) []*model.ConfigFileReleaseHistory { 195 var ( 196 histories = make([]*model.ConfigFileReleaseHistory, 0, len(ret)) 197 beginIndex = offset 198 endIndex = beginIndex + limit 199 totalCount = uint32(len(ret)) 200 ) 201 202 if totalCount == 0 { 203 return histories 204 } 205 if beginIndex >= endIndex { 206 return histories 207 } 208 if beginIndex >= totalCount { 209 return histories 210 } 211 if endIndex > totalCount { 212 endIndex = totalCount 213 } 214 for k := range ret { 215 histories = append(histories, ret[k].(*model.ConfigFileReleaseHistory)) 216 } 217 218 sort.Slice(histories, func(i, j int) bool { 219 return histories[i].Id > histories[j].Id 220 }) 221 222 return histories[beginIndex:endIndex] 223 }