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  }