package storage import ( "encoding/json" "fmt" "intent-system/pkg/itypes" "os" "strings" "github.com/civet148/log" "github.com/syndtr/goleveldb/leveldb" ) const ( LEVEL_DB_KEY_PREFFIX_CONTEXT = "/context/" //the last '/' cannot be removed ) type ContextMap map[string]*itypes.Context type LocalStorage struct { ldb *leveldb.DB } var Store *LocalStorage func init() { Store = NewLocalStorage() } func NewLocalStorage() *LocalStorage { return &LocalStorage{} } func (s *LocalStorage) open() (err error) { s.ldb, err = leveldb.OpenFile(itypes.DefaultLevelDBHome, nil) if err != nil { return fmt.Errorf("open level db path [%s] error [%s]", itypes.DefaultLevelDBHome, err.Error()) } return } func (s *LocalStorage) close() (err error) { return s.ldb.Close() } func (s *LocalStorage) delete(strKey string) (err error) { return s.ldb.Delete([]byte(strKey), nil) } func (s *LocalStorage) put(strKey string, data []byte) (err error) { if err = s.ldb.Put([]byte(strKey), data, nil); err != nil { log.Errorf("level db put [%s] error [%s]", strKey, err) return } return } func (s *LocalStorage) clean() error { return os.RemoveAll(itypes.DefaultLevelDBHome) } func (s *LocalStorage) get(strKey string) []byte { data, err := s.ldb.Get([]byte(strKey), nil) if err != nil { log.Errorf("level db get [%s] error [%s]", strKey, err) return nil } return data } // clean storage directory func (s *LocalStorage) Clean() error { return s.clean() } func (s *LocalStorage) DeleteContext(strAuthToken string) { var strKey = s.MakeContextKey(strAuthToken) if err := s.open(); err != nil { log.Errorf(err.Error()) return } defer s.close() if err := s.delete(strKey); err != nil { log.Errorf(err.Error()) } } func (s *LocalStorage) PutContext(ctx *itypes.Context) (err error) { var data []byte data, err = json.Marshal(ctx) if err != nil { log.Errorf("json marshal error [%s]", err) return } if err = s.open(); err != nil { log.Errorf(err.Error()) return } defer s.close() var strKey = s.MakeContextKey(ctx.AuthToken()) if err = s.put(strKey, data); err != nil { log.Errorf("level db put error [%s]", err) return } return } func (s *LocalStorage) LoadContexts() (contexts ContextMap, err error) { contexts = make(ContextMap) if err = s.open(); err != nil { log.Errorf(err.Error()) return } defer s.close() iter := s.ldb.NewIterator(nil, nil) for iter.Next() { strKey := string(iter.Key()) value := iter.Value() if strings.HasPrefix(strKey, LEVEL_DB_KEY_PREFFIX_CONTEXT) { strKey = strings.TrimPrefix(strKey, LEVEL_DB_KEY_PREFFIX_CONTEXT) var ctx = &itypes.Context{} if err = json.Unmarshal(value, ctx); err != nil { log.Errorf("key [%s] value unmarshal error [%s]", strKey, err) continue } contexts[strKey] = ctx log.Debugf("load user token [%v] context [%+v] from level db ok", strKey, ctx.Session) } } iter.Release() return } func (s *LocalStorage) MakeContextKey(strAuthToken string) string { strKey := fmt.Sprintf("%s%v", LEVEL_DB_KEY_PREFFIX_CONTEXT, strAuthToken) return strKey }