mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 04:07:47 +08:00
improve session storage interface for gsession
This commit is contained in:
parent
6d55b30b39
commit
f128cb9f61
@ -40,13 +40,12 @@
|
||||
## 功能改进
|
||||
|
||||
1. `ghttp`
|
||||
- 当`WebServer`产生`panic`异常错误时,默认打印调用链堆栈到错误日志中;
|
||||
- `Cookie`及`Session`的`TTL`配置数据类型修改为`time.Duration`;
|
||||
- 新增允许同时通过`Header/Cookie`传递`SessionId`;
|
||||
- 新增`ConfigFromMap/SetConfigWithMap`方法,支持通过`map`参数设置WebServer;
|
||||
- 改进默认的`CORS`配置,增加对常见`Header`参数的默认支持;
|
||||
- 新增`IsExitError`方法,用于开发者自定义处理`recover`错误处理时,过滤框架本身自定义的非异常错误;
|
||||
- 新增`SetSessionStorage`方法,用于开发者自定义`Session`存储;
|
||||
- 新增`SetSessionStorage`配置方法,用于开发者自定义`Session`存储;
|
||||
- `ghttp.Request`新增更多的参数获取方法;
|
||||
1. `gdb`
|
||||
- 增加对SQL中部分字段的自动转义(`Quote`)功能;
|
||||
@ -54,6 +53,7 @@
|
||||
- 增加`SetLogger`方法用于开发者自定义数据库的日志打印;
|
||||
- 增加`Master/Slave`方法,开发者可自主选择数据库操作执行的主从节点;
|
||||
- 增加对`mssql/pgsql/oracle`的单元测试;
|
||||
- `debug`模式支持完整带参数整合的SQL语句调试打印;
|
||||
- 增加了更多的功能方法;
|
||||
1. `glog`
|
||||
- 新增`Default`方法用于获取默认的`Logger`对象;
|
||||
|
@ -32,7 +32,7 @@ func (s *Session) init() {
|
||||
s.dirty = gtype.NewBool(false)
|
||||
}
|
||||
if len(s.id) > 0 && s.data == nil {
|
||||
if data := s.manager.storage.Get(s.id); data != nil {
|
||||
if data := s.manager.storage.GetSession(s.id); data != nil {
|
||||
if s.data = gmap.NewStrAnyMapFrom(data, true); s.data == nil {
|
||||
panic("session restoring failed for id:" + s.id)
|
||||
}
|
||||
@ -51,6 +51,73 @@ func (s *Session) init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets key-value pair to this session.
|
||||
func (s *Session) Set(key string, value interface{}) error {
|
||||
s.init()
|
||||
if err := s.manager.storage.Set(key, value); err != nil {
|
||||
if err == ErrorDisabled {
|
||||
s.data.Set(key, value)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.dirty.Set(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets batch sets the session using map.
|
||||
func (s *Session) Sets(data map[string]interface{}) error {
|
||||
s.init()
|
||||
if err := s.manager.storage.SetMap(data); err != nil {
|
||||
if err == ErrorDisabled {
|
||||
s.data.Sets(data)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.dirty.Set(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes key along with its value from this session.
|
||||
func (s *Session) Remove(key string) error {
|
||||
if len(s.id) == 0 {
|
||||
return nil
|
||||
}
|
||||
s.init()
|
||||
if err := s.manager.storage.Remove(key); err != nil {
|
||||
if err == ErrorDisabled {
|
||||
s.data.Remove(key)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.dirty.Set(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clear is alias of RemoveAll.
|
||||
func (s *Session) Clear() error {
|
||||
return s.RemoveAll()
|
||||
}
|
||||
|
||||
// RemoveAll deletes all key-value pairs from this session.
|
||||
func (s *Session) RemoveAll() error {
|
||||
if len(s.id) == 0 {
|
||||
return nil
|
||||
}
|
||||
s.init()
|
||||
if err := s.manager.storage.RemoveAll(); err != nil {
|
||||
if err == ErrorDisabled {
|
||||
s.data.Clear()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.dirty.Set(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Id returns the session id for this session.
|
||||
// It create and returns a new session id if the session id is not passed in initialization.
|
||||
func (s *Session) Id() string {
|
||||
@ -63,6 +130,9 @@ func (s *Session) Id() string {
|
||||
func (s *Session) Map() map[string]interface{} {
|
||||
if len(s.id) > 0 {
|
||||
s.init()
|
||||
if data := s.manager.storage.GetMap(); data != nil {
|
||||
return data
|
||||
}
|
||||
return s.data.Map()
|
||||
}
|
||||
return nil
|
||||
@ -72,29 +142,18 @@ func (s *Session) Map() map[string]interface{} {
|
||||
func (s *Session) Size() int {
|
||||
if len(s.id) > 0 {
|
||||
s.init()
|
||||
if size := s.manager.storage.GetSize(s.id); size >= 0 {
|
||||
return size
|
||||
}
|
||||
return s.data.Size()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Set sets key-value pair to this session.
|
||||
func (s *Session) Set(key string, value interface{}) {
|
||||
s.init()
|
||||
s.data.Set(key, value)
|
||||
s.dirty.Set(true)
|
||||
}
|
||||
|
||||
// Sets batch sets the session using map.
|
||||
func (s *Session) Sets(m map[string]interface{}) {
|
||||
s.init()
|
||||
s.data.Sets(m)
|
||||
s.dirty.Set(true)
|
||||
}
|
||||
|
||||
// Contains checks whether key exist in the session.
|
||||
func (s *Session) Contains(key string) bool {
|
||||
s.init()
|
||||
return s.data.Contains(key)
|
||||
return s.Get(key) != nil
|
||||
}
|
||||
|
||||
// IsDirty checks whether there's any data changes in the session.
|
||||
@ -105,22 +164,6 @@ func (s *Session) IsDirty() bool {
|
||||
return s.dirty.Val()
|
||||
}
|
||||
|
||||
// Remove removes key along with its value from this session.
|
||||
func (s *Session) Remove(key string) {
|
||||
s.init()
|
||||
s.data.Remove(key)
|
||||
s.dirty.Set(true)
|
||||
}
|
||||
|
||||
// Clear deletes all key-value pairs from this session.
|
||||
func (s *Session) Clear() {
|
||||
if len(s.id) > 0 {
|
||||
s.init()
|
||||
s.data.Clear()
|
||||
s.dirty.Set(true)
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes current session and updates its ttl in the session manager.
|
||||
// If this session is dirty, it also exports it to storage.
|
||||
//
|
||||
@ -130,7 +173,7 @@ func (s *Session) Close() {
|
||||
if s.manager.storage != nil {
|
||||
if s.dirty.Cas(true, false) {
|
||||
s.data.RLockFunc(func(m map[string]interface{}) {
|
||||
if err := s.manager.storage.Set(s.id, m); err != nil {
|
||||
if err := s.manager.storage.SetSession(s.id, m); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
@ -144,12 +187,19 @@ func (s *Session) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves session value with given key.
|
||||
// It returns <def> if the key does not exist in the session if <def> is given,
|
||||
// or else it return nil.
|
||||
func (s *Session) Get(key string, def ...interface{}) interface{} {
|
||||
if len(s.id) > 0 {
|
||||
if len(s.id) == 0 {
|
||||
return nil
|
||||
}
|
||||
s.init()
|
||||
if v := s.data.Get(key); v != nil {
|
||||
if v := s.manager.storage.Get(key); v != nil {
|
||||
return v
|
||||
}
|
||||
if v := s.data.Get(key); v != nil {
|
||||
return v
|
||||
}
|
||||
if len(def) > 0 {
|
||||
return def[0]
|
||||
|
@ -7,11 +7,29 @@
|
||||
package gsession
|
||||
|
||||
type Storage interface {
|
||||
// Get returns the session data bytes for given session id.
|
||||
Get(id string) map[string]interface{}
|
||||
// Set updates the content for session id.
|
||||
// Get retrieves session value with given key.
|
||||
// It returns nil if the key does not exist in the session.
|
||||
Get(key string) interface{}
|
||||
// GetMap retrieves all key-value pairs as map from storage.
|
||||
GetMap() map[string]interface{}
|
||||
// GetSize retrieves the size of key-value pairs from storage.
|
||||
GetSize(id string) int
|
||||
|
||||
// Set sets key-value session pair to the storage.
|
||||
Set(key string, value interface{}) error
|
||||
// SetMap batch sets key-value session pairs with map to the storage.
|
||||
SetMap(data map[string]interface{}) error
|
||||
|
||||
// Remove deletes key with its value from storage.
|
||||
Remove(key string) error
|
||||
// RemoveAll deletes all key-value pairs from storage.
|
||||
RemoveAll() error
|
||||
|
||||
// GetSession returns the session data bytes for given session id.
|
||||
GetSession(id string) map[string]interface{}
|
||||
// SetSession updates the content for session id.
|
||||
// Note that the parameter <content> is the serialized bytes for session map.
|
||||
Set(id string, data map[string]interface{}) error
|
||||
// UpdateTTL updates the TTL for session id.
|
||||
SetSession(id string, data map[string]interface{}) error
|
||||
// UpdateTTL updates the TTL for specified session id.
|
||||
UpdateTTL(id string) error
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ package gsession
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@ -39,6 +40,7 @@ var (
|
||||
DefaultStorageFileCryptoKey = []byte("Session storage file crypto key!")
|
||||
DefaultStorageFileCryptoEnabled = false
|
||||
DefaultStorageFileLoopInterval = time.Minute
|
||||
ErrorDisabled = errors.New("this feature is disabled in this storage")
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -96,8 +98,44 @@ func (s *StorageFile) sessionFilePath(id string) string {
|
||||
return gfile.Join(s.path, id)
|
||||
}
|
||||
|
||||
// Get return the session data for given session id.
|
||||
func (s *StorageFile) Get(id string) map[string]interface{} {
|
||||
// Get retrieves session value with given key.
|
||||
// It returns nil if the key does not exist in the session.
|
||||
func (s *StorageFile) Get(key string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMap retrieves all key-value pairs as map from storage.
|
||||
func (s *StorageFile) GetMap() map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSize retrieves the size of key-value pairs from storage.
|
||||
func (s *StorageFile) GetSize(id string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Set sets key-value session pair to the storage.
|
||||
func (s *StorageFile) Set(key string, value interface{}) error {
|
||||
return ErrorDisabled
|
||||
}
|
||||
|
||||
// SetMap batch sets key-value session pairs with map to the storage.
|
||||
func (s *StorageFile) SetMap(data map[string]interface{}) error {
|
||||
return ErrorDisabled
|
||||
}
|
||||
|
||||
// Remove deletes key with its value from storage.
|
||||
func (s *StorageFile) Remove(key string) error {
|
||||
return ErrorDisabled
|
||||
}
|
||||
|
||||
// RemoveAll deletes all key-value pairs from storage.
|
||||
func (s *StorageFile) RemoveAll() error {
|
||||
return ErrorDisabled
|
||||
}
|
||||
|
||||
// GetSession return the session data for given session id.
|
||||
func (s *StorageFile) GetSession(id string) map[string]interface{} {
|
||||
path := s.sessionFilePath(id)
|
||||
data := gfile.GetBytes(path)
|
||||
if len(data) > 8 {
|
||||
@ -123,9 +161,9 @@ func (s *StorageFile) Get(id string) map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set updates the content for session id.
|
||||
// SetSession updates the content for session id.
|
||||
// Note that the parameter <content> is the serialized bytes for session map.
|
||||
func (s *StorageFile) Set(id string, data map[string]interface{}) error {
|
||||
func (s *StorageFile) SetSession(id string, data map[string]interface{}) error {
|
||||
path := s.sessionFilePath(id)
|
||||
content, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
@ -151,7 +189,7 @@ func (s *StorageFile) Set(id string, data map[string]interface{}) error {
|
||||
return file.Close()
|
||||
}
|
||||
|
||||
// UpdateTTL updates the TTL for session id.
|
||||
// UpdateTTL updates the TTL for specified session id.
|
||||
// It just adds the session id to the async handling queue.
|
||||
func (s *StorageFile) UpdateTTL(id string) error {
|
||||
s.updatingIdSet.Add(id)
|
||||
|
Loading…
Reference in New Issue
Block a user