github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/meta/label.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package meta 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "strconv" 21 "strings" 22 23 "github.com/pingcap/errors" 24 "github.com/vescale/zgraph/parser/model" 25 ) 26 27 func (*Meta) labelKey(labelID int64) []byte { 28 return LabelKey(labelID) 29 } 30 31 // LabelKey encodes the labelID into label key. 32 func LabelKey(labelID int64) []byte { 33 return []byte(fmt.Sprintf("%s:%d", mLabelPrefix, labelID)) 34 } 35 36 // IsLabelKey checks whether the label key comes from LabelKey(). 37 func IsLabelKey(labelKey []byte) bool { 38 return strings.HasPrefix(string(labelKey), mLabelPrefix+":") 39 } 40 41 // ParseLabelKey decodes the label key to get label id. 42 func ParseLabelKey(labelKey []byte) (int64, error) { 43 if !strings.HasPrefix(string(labelKey), mLabelPrefix) { 44 return 0, ErrInvalidString 45 } 46 47 labelID := strings.TrimPrefix(string(labelKey), mLabelPrefix+":") 48 id, err := strconv.Atoi(labelID) 49 return int64(id), errors.Trace(err) 50 } 51 52 func (m *Meta) checkLabelExists(graphKey []byte, labelKey []byte) error { 53 v, err := m.txn.HGet(graphKey, labelKey) 54 if err == nil && v == nil { 55 err = ErrLabelNotExists 56 } 57 return errors.Trace(err) 58 } 59 60 func (m *Meta) checkLabelNotExists(graphKey []byte, labelKey []byte) error { 61 v, err := m.txn.HGet(graphKey, labelKey) 62 if err == nil && v != nil { 63 err = ErrLabelExists 64 } 65 return errors.Trace(err) 66 } 67 68 // CreateLabel creates a label. 69 func (m *Meta) CreateLabel(graphID int64, labelInfo *model.LabelInfo) error { 70 // Check if graph exists. 71 graphKey := m.graphKey(graphID) 72 if err := m.checkGraphExists(graphKey); err != nil { 73 return errors.Trace(err) 74 } 75 76 // Check if label exists. 77 lableKey := m.labelKey(labelInfo.ID) 78 if err := m.checkLabelNotExists(graphKey, lableKey); err != nil { 79 return errors.Trace(err) 80 } 81 82 data, err := json.Marshal(labelInfo) 83 if err != nil { 84 return errors.Trace(err) 85 } 86 87 return m.txn.HSet(graphKey, lableKey, data) 88 } 89 90 // UpdateLabel updates the label. 91 func (m *Meta) UpdateLabel(graphID int64, labelInfo *model.LabelInfo) error { 92 // Check if graph exists. 93 graphKey := m.graphKey(graphID) 94 if err := m.checkGraphExists(graphKey); err != nil { 95 return errors.Trace(err) 96 } 97 98 // Check if label exists. 99 labelKey := m.labelKey(labelInfo.ID) 100 if err := m.checkLabelExists(graphKey, labelKey); err != nil { 101 return errors.Trace(err) 102 } 103 104 data, err := json.Marshal(labelInfo) 105 if err != nil { 106 return errors.Trace(err) 107 } 108 109 err = m.txn.HSet(graphKey, labelKey, data) 110 return errors.Trace(err) 111 } 112 113 // DropLabel drops label in graph. 114 func (m *Meta) DropLabel(graphID int64, labelID int64) error { 115 // Check if graph exists. 116 graphKey := m.graphKey(graphID) 117 if err := m.checkGraphExists(graphKey); err != nil { 118 return errors.Trace(err) 119 } 120 121 // Check if label exists. 122 labelKey := m.labelKey(labelID) 123 if err := m.checkLabelExists(graphKey, labelKey); err != nil { 124 return errors.Trace(err) 125 } 126 127 if err := m.txn.HDel(graphKey, labelKey); err != nil { 128 return errors.Trace(err) 129 } 130 return nil 131 } 132 133 // ListLabels shows all labels in a graph. 134 func (m *Meta) ListLabels(graphID int64) ([]*model.LabelInfo, error) { 135 graphKey := m.graphKey(graphID) 136 if err := m.checkGraphExists(graphKey); err != nil { 137 return nil, errors.Trace(err) 138 } 139 140 res, err := m.txn.HGetAll(graphKey) 141 if err != nil { 142 return nil, errors.Trace(err) 143 } 144 145 labels := make([]*model.LabelInfo, 0, len(res)/2) 146 for _, r := range res { 147 // only handle label meta 148 labelKey := string(r.Field) 149 if !strings.HasPrefix(labelKey, mLabelPrefix) { 150 continue 151 } 152 153 tbInfo := &model.LabelInfo{} 154 err = json.Unmarshal(r.Value, tbInfo) 155 if err != nil { 156 return nil, errors.Trace(err) 157 } 158 159 labels = append(labels, tbInfo) 160 } 161 162 return labels, nil 163 } 164 165 // GetLabel gets the label value in a graph. 166 func (m *Meta) GetLabel(graphID int64, labelID int64) (*model.LabelInfo, error) { 167 // Check if graph exists. 168 graphKey := m.graphKey(graphID) 169 if err := m.checkGraphExists(graphKey); err != nil { 170 return nil, errors.Trace(err) 171 } 172 173 labelKey := m.labelKey(labelID) 174 value, err := m.txn.HGet(graphKey, labelKey) 175 if err != nil || value == nil { 176 return nil, errors.Trace(err) 177 } 178 179 labelInfo := &model.LabelInfo{} 180 err = json.Unmarshal(value, labelInfo) 181 return labelInfo, errors.Trace(err) 182 }