github.com/yusys-cloud/go-jsonstore-rest@v0.0.0-20230228115429-0a54aa4a27a6/rest/storage.go (about) 1 // Author: yangzq80@gmail.com 2 // Date: 2021-03-16 3 package rest 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "github.com/bwmarrin/snowflake" 9 log "github.com/sirupsen/logrus" 10 "github.com/thedevsaddam/gojsonq/v2" 11 "github.com/xujiajun/utils/filesystem" 12 "github.com/yusys-cloud/go-jsonstore-rest/jsonstore" 13 "github.com/yusys-cloud/go-jsonstore-rest/model" 14 "os" 15 "regexp" 16 "strconv" 17 "time" 18 ) 19 20 type Storage struct { 21 buckets map[string]*jsonstore.JSONStore 22 dir string 23 IdNode *snowflake.Node 24 } 25 26 type Search struct { 27 B string `form:"b"` 28 K string `form:"k"` 29 Node string `form:"node"` 30 Key string `form:"key"` // Search conditions key 31 Value string `form:"value"` // Search conditions value 32 Relation string `form:"relation"` // Search relation,default equal; equal,like 33 ShortBy string `form:"shortBy"` 34 Page int `form:"page"` 35 Size int `form:"size"` 36 } 37 38 const ( 39 CACHE_BUCKET string = "meta" 40 ) 41 42 func NewStorage(dir string) *Storage { 43 log.Println("Init JSON storage...", dir) 44 //create dir 45 mkdirIfNotExist(dir) 46 47 node, _ := snowflake.NewNode(1) 48 49 return &Storage{buckets: make(map[string]*jsonstore.JSONStore), dir: dir, IdNode: node} 50 } 51 52 func (s *Storage) bucket(bucket string) *jsonstore.JSONStore { 53 // From memory 54 if s.buckets[bucket] != nil { 55 return s.buckets[bucket] 56 } 57 // From local 58 if ss, err := jsonstore.Open(s.getFileName(bucket)); err == nil { 59 s.buckets[bucket] = ss 60 return s.buckets[bucket] 61 } 62 // New json storage 63 s.buckets[bucket] = new(jsonstore.JSONStore) 64 return s.buckets[bucket] 65 } 66 67 // 查询bucket中 key 全部 68 func (s *Storage) ReadAll(bucket string, key string) *model.Response { 69 70 resp := model.NewResponse() 71 72 rs := s.bucket(bucket).GetAll(regexp.MustCompile(key)) 73 74 resp.Data.Total = len(rs) 75 resp.Data.Items = convertMapToArray(rs) 76 77 return resp 78 } 79 func (s *Storage) ReadAllSort(bucket string, key string) *model.Response { 80 81 resp := model.NewResponse() 82 83 rs := s.bucket(bucket).GetAll(regexp.MustCompile(key)) 84 85 resp.Data.Total = len(rs) 86 b, _ := json.Marshal(convertMapToArray(rs)) 87 88 jq := gojsonq.New().FromString(string(b)) 89 jq.SortBy("k", "desc") 90 91 resp.Data.Items = jq.Get() 92 return resp 93 } 94 95 // 查询单个 96 func (s *Storage) Read(bucket string, key string) model.Data { 97 98 _, rs := s.bucket(bucket).GetRawMessage(key) 99 100 var f interface{} 101 102 json.Unmarshal(rs, &f) 103 104 return model.Data{key, f} 105 } 106 107 // 查询单个,返回 Struct 对象 108 func (s *Storage) ReadOneStruct(bucket string, key string, v interface{}) error { 109 110 error := s.bucket(bucket).Get(key, v) 111 112 return error 113 } 114 115 func (s *Storage) ReadOneRaw(bucket string, key string) []byte { 116 117 _, rs := s.bucket(bucket).GetRawMessage(key) 118 119 return rs 120 } 121 122 // 保存key,value. bucket类似table 123 func (s *Storage) Create(bucket string, key string, value interface{}) model.Data { 124 125 //默认自增ID 126 id := key + ":" + s.IdNode.Generate().String() 127 128 err := s.bucket(bucket).Set(id, value) 129 if err != nil { 130 log.Error(err.Error()) 131 } 132 133 s.savePersistent(bucket) 134 135 return s.Read(bucket, id) 136 } 137 138 // 根据key更新 139 func (s *Storage) Update(bucket string, key string, value interface{}) model.Data { 140 141 err := s.bucket(bucket).Set(key, value) 142 if err != nil { 143 log.Error(err.Error()) 144 } 145 146 s.savePersistent(bucket) 147 148 return s.Read(bucket, key) 149 } 150 func (s *Storage) UpdateWeight(bucket string, kid string) interface{} { 151 152 d := s.Read(bucket, kid) 153 154 i := d.V.(map[string]interface{}) 155 i["weight"] = strconv.FormatInt(time.Now().Unix(), 10) 156 157 err := s.bucket(bucket).Set(kid, i) 158 if err != nil { 159 log.Error(err.Error()) 160 } 161 162 s.savePersistent(bucket) 163 164 return i 165 } 166 func (s *Storage) UpdateMarshalValue(bucket string, key string, value []byte) error { 167 168 err := s.bucket(bucket).SetMarshalValue(key, value) 169 if err != nil { 170 log.Error(err.Error()) 171 } 172 173 s.savePersistent(bucket) 174 175 return err 176 } 177 178 // 根据key删除 179 func (s *Storage) Delete(bucket string, key string) { 180 181 s.bucket(bucket).Delete(key) 182 183 s.savePersistent(bucket) 184 } 185 func (s *Storage) DeleteAll(bucket string, key string) int { 186 rs := s.ReadAll(bucket, key) 187 return s.DeleteList(bucket, rs.Data.Items, true) 188 } 189 190 func (s *Storage) DeleteList(bucket string, items interface{}, isData bool) int { 191 n := 0 192 if isData { 193 for _, value := range items.([]model.Data) { 194 s.bucket(bucket).Delete(value.K) 195 n++ 196 } 197 } else { 198 for _, value := range items.([]interface{}) { 199 s.bucket(bucket).Delete(value.(map[string]interface{})["k"].(string)) 200 n++ 201 } 202 } 203 s.savePersistent(bucket) 204 return n 205 } 206 207 func (s *Storage) savePersistent(bucket string) { 208 // Saving will automatically gzip if .gz is provided 209 if err := jsonstore.Save(s.bucket(bucket), s.getFileName(bucket)); err != nil { 210 log.Error(err) 211 } 212 } 213 214 func (s *Storage) getFileName(bucket string) string { 215 return s.dir + "/" + bucket + ".json.gz" 216 } 217 218 func mkdirIfNotExist(rootDir string) error { 219 if ok := filesystem.PathIsExist(rootDir); !ok { 220 if err := os.MkdirAll(rootDir, os.ModePerm); err != nil { 221 fmt.Println(err) 222 return err 223 } 224 } 225 return nil 226 } 227 228 func convertMapToArray(raw map[string]json.RawMessage) []model.Data { 229 datas := make([]model.Data, 0) 230 for k, v := range raw { 231 datas = append(datas, model.Data{k, v}) 232 } 233 return datas 234 }