github.com/polarismesh/polaris@v1.17.8/store/mysql/namespace.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 sqldb 19 20 import ( 21 "database/sql" 22 "errors" 23 "fmt" 24 "time" 25 26 "github.com/polarismesh/polaris/common/model" 27 "github.com/polarismesh/polaris/store" 28 ) 29 30 // namespaceStore 实现了NamespaceStore 31 type namespaceStore struct { 32 master *BaseDB // 大部分操作都用主数据库 33 slave *BaseDB // 缓存相关的读取,请求到slave 34 } 35 36 // AddNamespace 添加命名空间 37 func (ns *namespaceStore) AddNamespace(namespace *model.Namespace) error { 38 if namespace.Name == "" { 39 return errors.New("store add namespace name is empty") 40 } 41 return RetryTransaction("addNamespace", func() error { 42 return ns.master.processWithTransaction("addNamespace", func(tx *BaseTx) error { 43 // 先删除无效数据,再添加新数据 44 if err := cleanNamespace(tx, namespace.Name); err != nil { 45 return err 46 } 47 48 str := "insert into namespace(name, comment, token, owner, ctime, mtime) values(?,?,?,?,sysdate(),sysdate())" 49 if _, err := tx.Exec(str, namespace.Name, namespace.Comment, namespace.Token, namespace.Owner); err != nil { 50 return store.Error(err) 51 } 52 53 if err := tx.Commit(); err != nil { 54 log.Errorf("[Store][database] batch delete instance commit tx err: %s", err.Error()) 55 return err 56 } 57 58 return nil 59 }) 60 }) 61 } 62 63 // UpdateNamespace 更新命名空间,目前只更新owner 64 func (ns *namespaceStore) UpdateNamespace(namespace *model.Namespace) error { 65 if namespace.Name == "" { 66 return errors.New("store update namespace name is empty") 67 } 68 return RetryTransaction("updateNamespace", func() error { 69 return ns.master.processWithTransaction("updateNamespace", func(tx *BaseTx) error { 70 str := "update namespace set owner = ?, comment = ?,mtime = sysdate() where name = ?" 71 if _, err := tx.Exec(str, namespace.Owner, namespace.Comment, namespace.Name); err != nil { 72 return store.Error(err) 73 } 74 75 if err := tx.Commit(); err != nil { 76 log.Errorf("[Store][database] batch delete instance commit tx err: %s", err.Error()) 77 return err 78 } 79 80 return nil 81 }) 82 }) 83 } 84 85 // UpdateNamespaceToken 更新命名空间token 86 func (ns *namespaceStore) UpdateNamespaceToken(name string, token string) error { 87 if name == "" || token == "" { 88 return fmt.Errorf( 89 "store update namespace token some param are empty, name is %s, token is %s", name, token) 90 } 91 return RetryTransaction("updateNamespaceToken", func() error { 92 return ns.master.processWithTransaction("updateNamespaceToken", func(tx *BaseTx) error { 93 str := "update namespace set token = ?, mtime = sysdate() where name = ?" 94 if _, err := tx.Exec(str, token, name); err != nil { 95 return store.Error(err) 96 } 97 98 if err := tx.Commit(); err != nil { 99 log.Errorf("[Store][database] batch delete instance commit tx err: %s", err.Error()) 100 return err 101 } 102 103 return nil 104 }) 105 }) 106 } 107 108 // GetNamespace 根据名字获取命名空间详情,只返回有效的 109 func (ns *namespaceStore) GetNamespace(name string) (*model.Namespace, error) { 110 namespace, err := ns.getNamespace(name) 111 if err != nil { 112 return nil, err 113 } 114 115 if namespace != nil && !namespace.Valid { 116 return nil, nil 117 } 118 119 return namespace, nil 120 } 121 122 // GetNamespaces 根据过滤条件查询命名空间及数目 123 func (ns *namespaceStore) GetNamespaces(filter map[string][]string, offset, limit int) ( 124 []*model.Namespace, uint32, error) { 125 // 只查询有效数据 126 filter["flag"] = []string{"0"} 127 128 num, err := ns.getNamespacesCount(filter) 129 if err != nil { 130 return nil, 0, err 131 } 132 133 out, err := ns.getNamespaces(filter, offset, limit) 134 if err != nil { 135 return nil, 0, err 136 } 137 138 return out, num, nil 139 } 140 141 // GetMoreNamespaces 根据mtime获取命名空间 142 func (ns *namespaceStore) GetMoreNamespaces(mtime time.Time) ([]*model.Namespace, error) { 143 str := genNamespaceSelectSQL() + " where mtime >= FROM_UNIXTIME(?)" 144 rows, err := ns.slave.Query(str, timeToTimestamp(mtime)) 145 if err != nil { 146 log.Errorf("[Store][database] get more namespace query err: %s", err.Error()) 147 return nil, err 148 } 149 150 return namespaceFetchRows(rows) 151 } 152 153 // getNamespacesCount根据相关条件查询对应命名空间数目 154 func (ns *namespaceStore) getNamespacesCount(filter map[string][]string) (uint32, error) { 155 str := `select count(*) from namespace ` 156 str, args := genNamespaceWhereSQLAndArgs(str, filter, nil, 0, 1) 157 158 var count uint32 159 err := ns.master.QueryRow(str, args...).Scan(&count) 160 switch { 161 case err == sql.ErrNoRows: 162 log.Errorf("[Store][database] no row with this namespace filter") 163 return count, err 164 case err != nil: 165 log.Errorf("[Store][database] get namespace count by filter err: %s", err.Error()) 166 return count, err 167 default: 168 return count, err 169 } 170 } 171 172 // getNamespaces 根据相关条件查询对应命名空间 173 func (ns *namespaceStore) getNamespaces(filter map[string][]string, offset, limit int) ([]*model.Namespace, error) { 174 str := genNamespaceSelectSQL() 175 order := &Order{"mtime", "desc"} 176 str, args := genNamespaceWhereSQLAndArgs(str, filter, order, offset, limit) 177 178 rows, err := ns.master.Query(str, args...) 179 if err != nil { 180 log.Errorf("[Store][database] get namespaces by filter query err: %s", err.Error()) 181 return nil, err 182 } 183 184 return namespaceFetchRows(rows) 185 } 186 187 // getNamespace 获取namespace的内部函数,从数据库中拉取数据 188 func (ns *namespaceStore) getNamespace(name string) (*model.Namespace, error) { 189 if name == "" { 190 return nil, errors.New("store get namespace name is empty") 191 } 192 193 str := genNamespaceSelectSQL() + " where name = ?" 194 rows, err := ns.master.Query(str, name) 195 if err != nil { 196 log.Errorf("[Store][database] get namespace query err: %s", err.Error()) 197 return nil, err 198 } 199 200 out, err := namespaceFetchRows(rows) 201 if err != nil { 202 return nil, err 203 } 204 205 if len(out) == 0 { 206 return nil, nil 207 } 208 return out[0], nil 209 } 210 211 // clean真实的数据,只有flag=1的数据才可以清除 212 func cleanNamespace(tx *BaseTx, name string) error { 213 str := "delete from namespace where name = ? and flag = 1" 214 // 必须打印日志说明 215 log.Infof("[Store][database] clean namespace(%s)", name) 216 if _, err := tx.Exec(str, name); err != nil { 217 log.Infof("[Store][database] clean namespace(%s) err: %s", name, err.Error()) 218 return err 219 } 220 221 return nil 222 } 223 224 // rlockNamespace rlock namespace 225 func rlockNamespace(queryRow func(query string, args ...interface{}) *sql.Row, namespace string) ( 226 string, error) { 227 str := "select name from namespace where name = ? and flag != 1 lock in share mode" 228 229 var name string 230 err := queryRow(str, namespace).Scan(&name) 231 switch { 232 case err == sql.ErrNoRows: 233 return "", nil 234 case err != nil: 235 return "", err 236 default: 237 return name, nil 238 } 239 } 240 241 // genNamespaceSelectSQL 生成namespace的查询语句 242 func genNamespaceSelectSQL() string { 243 str := `select name, IFNULL(comment, ""), token, owner, flag, UNIX_TIMESTAMP(ctime), UNIX_TIMESTAMP(mtime) 244 from namespace ` 245 return str 246 } 247 248 // namespaceFetchRows 取出rows的数据 249 func namespaceFetchRows(rows *sql.Rows) ([]*model.Namespace, error) { 250 if rows == nil { 251 return nil, nil 252 } 253 defer rows.Close() 254 255 var out []*model.Namespace 256 var ctime, mtime int64 257 var flag int 258 259 for rows.Next() { 260 space := &model.Namespace{} 261 err := rows.Scan( 262 &space.Name, 263 &space.Comment, 264 &space.Token, 265 &space.Owner, 266 &flag, 267 &ctime, 268 &mtime) 269 if err != nil { 270 log.Errorf("[Store][database] fetch namespace rows scan err: %s", err.Error()) 271 return nil, err 272 } 273 274 space.CreateTime = time.Unix(ctime, 0) 275 space.ModifyTime = time.Unix(mtime, 0) 276 space.Valid = true 277 if flag == 1 { 278 space.Valid = false 279 } 280 281 out = append(out, space) 282 } 283 if err := rows.Err(); err != nil { 284 log.Errorf("[Store][database] fetch namespace rows next err: %s", err.Error()) 285 return nil, err 286 } 287 288 return out, nil 289 }