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  }