| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- package core
- import (
- "encoding/json"
- "io/ioutil"
- "path/filepath"
- "sync"
- "time"
- "github.com/cdle/sillyplus/utils"
- )
- var temp *PersistentKeyValueStore
- var tempPath = filepath.Join(utils.GetDataHome(), "cache.json")
- var cache = func(pre string, sec int) interface{} {
- return map[string]interface{}{
- "set": func(key string, value interface{}, num int) {
- if sec != 0 && num == 0 {
- num = sec
- }
- temp.Set(pre+"_"+key, value, num)
- },
- "get": func(key string, def interface{}) interface{} {
- v := temp.Get(pre + "_" + key)
- if v == nil {
- v = def
- }
- return v
- },
- "delete": func(key string) {
- temp.Delete(pre + "_" + key)
- },
- }
- }
- type PersistentKeyValueStore struct {
- sync.RWMutex
- data map[string]Value
- }
- type Value struct {
- Data interface{} `json:"data"`
- ExpiredAt time.Time `json:"expired_at"`
- }
- func NewPersistentKeyValueStore() *PersistentKeyValueStore {
- return &PersistentKeyValueStore{
- data: make(map[string]Value),
- }
- }
- func (s *PersistentKeyValueStore) Set(key string, value interface{}, dur int) error {
- s.Lock()
- defer s.Unlock()
- if dur == 0 {
- dur = 86400
- }
- expiredAt := time.Now().Add(time.Duration(dur) * time.Second)
- s.data[key] = Value{
- Data: value,
- ExpiredAt: expiredAt,
- }
- go func() {
- s.RLock()
- defer s.RUnlock()
- defer func() {
- recover()
- }()
- jsonBytes, err := json.Marshal(s.data)
- if err == nil {
- ioutil.WriteFile(tempPath, jsonBytes, 0644)
- }
- }()
- return nil
- }
- func (s *PersistentKeyValueStore) Get(key string) interface{} {
- s.RLock()
- defer s.RUnlock()
- value, ok := s.data[key]
- if !ok || time.Now().After(value.ExpiredAt) {
- return nil
- }
- return value.Data
- }
- func (s *PersistentKeyValueStore) Delete(key string) error {
- s.Lock()
- defer s.Unlock()
- delete(s.data, key)
- // Serialize data to JSON and write to file
- jsonBytes, err := json.Marshal(s.data)
- if err != nil {
- return err
- }
- err = ioutil.WriteFile(tempPath, jsonBytes, 0644)
- if err != nil {
- return err
- }
- return nil
- }
- func (s *PersistentKeyValueStore) LoadFromFile() error {
- s.Lock()
- defer s.Unlock()
- // Read data from file
- jsonBytes, err := ioutil.ReadFile(tempPath)
- if err != nil {
- return err
- }
- // Deserialize JSON data
- err = json.Unmarshal(jsonBytes, &s.data)
- if err != nil {
- return err
- }
- // Delete expired data
- now := time.Now()
- for key, value := range s.data {
- if now.After(value.ExpiredAt) {
- delete(s.data, key)
- }
- }
- // Serialize data to JSON and write to file
- jsonBytes, err = json.Marshal(s.data)
- if err != nil {
- return err
- }
- err = ioutil.WriteFile(tempPath, jsonBytes, 0644)
- if err != nil {
- return err
- }
- return nil
- }
- func init() {
- temp = NewPersistentKeyValueStore()
- // Load data from file
- temp.LoadFromFile()
- // if err != nil {
- // fmt.Println("Failed to load data from file:", err)
- // }
- // // Set a key-value pair
- // err = store.Set("foo", map[string]interface{}{
- // "bar": "baz",
- // }, 1000)
- // if err != nil {
- // fmt.Println("Failed to set key-value pair:", err)
- // }
- // // Get a value
- // value := store.Get("foo")
- // fmt.Println(value)
- // // Delete a key-value pair
- // err = store.Delete("foo")
- // if err != nil {
- // fmt.Println("Failed to delete key-value pair:", err)
- // }
- }
|