diff --git a/model/convert.go b/model/convert.go new file mode 100644 index 0000000..ab1f011 --- /dev/null +++ b/model/convert.go @@ -0,0 +1,39 @@ +package model + +import ( + "encoding/json" + "sync" +) + +func JsonByteToSyncSession(jsonByte []byte) (*SyncSession, error) { + s := &Session{} + err := json.Unmarshal(jsonByte, s) + if err != nil { + return nil, err + } + + return ConvertSyncSession(s), nil +} + +func JsonToSyncSession(jsonStr string) (*SyncSession, error) { + return JsonByteToSyncSession([]byte(jsonStr)) +} + +// ConvertSyncSession convert to Session +func ConvertSyncSession(s *Session) *SyncSession { + session := &SyncSession{ + Id: s.Id, + Type: s.Type, + LoginType: s.LoginType, + LoginId: s.LoginId, + Token: s.Token, + CreateTime: s.CreateTime, + DataMap: &sync.Map{}, + TokenSignList: s.TokenSignList, + } + // copy DataMap + for k, v := range s.DataMap { + session.DataMap.Store(k, v) + } + return session +} diff --git a/model/session.go b/model/session.go index 1a96bba..926cf77 100644 --- a/model/session.go +++ b/model/session.go @@ -3,7 +3,6 @@ package model import ( "container/list" "encoding/json" - "sync" "time" ) @@ -19,13 +18,14 @@ type Session struct { LoginId string Token string CreateTime int64 - DataMap *sync.Map + DataMap map[string]interface{} TokenSignList []*TokenSign `json:"TokenSignList"` } func DefaultSession(id string) *Session { return &Session{ Id: id, + DataMap: make(map[string]interface{}), CreateTime: time.Now().UnixMilli(), TokenSignList: make([]*TokenSign, 0), } @@ -37,6 +37,7 @@ func NewSession(id string, sessionType string, loginId string) *Session { Type: sessionType, LoginId: loginId, CreateTime: time.Now().UnixMilli(), + DataMap: make(map[string]interface{}), TokenSignList: make([]*TokenSign, 0), } } @@ -131,8 +132,9 @@ func (s *Session) Json() string { return string(b) } +// Get returns data from DataMap func (s *Session) Get(key string) interface{} { - value, ok := s.DataMap.Load(key) + value, ok := s.DataMap[key] if !ok { return nil } @@ -140,5 +142,17 @@ func (s *Session) Get(key string) interface{} { } func (s *Session) Set(key string, obj interface{}) { - s.DataMap.Store(key, obj) + s.DataMap[key] = obj +} + +// GetOrSet returns the existing value for the key if present. +// Otherwise, it stores and returns the given value. +// The loaded result is true if the value was loaded, false if stored. +func (s *Session) GetOrSet(key string, obj interface{}) (interface{}, bool) { + value := s.Get(key) + if value == nil { + s.Set(key, obj) + return obj, false + } + return value, true } diff --git a/model/sync_session.go b/model/sync_session.go new file mode 100644 index 0000000..cba966c --- /dev/null +++ b/model/sync_session.go @@ -0,0 +1,177 @@ +package model + +import ( + "container/list" + "encoding/json" + "fmt" + "sync" + "time" +) + +// SyncSession sync SyncSession +type SyncSession struct { + Id string + Type string + LoginType string + LoginId string + Token string + CreateTime int64 + DataMap *sync.Map + TokenSignList []*TokenSign `json:"TokenSignList"` +} + +func DefaultSyncSession(id string) *SyncSession { + return &SyncSession{ + Id: id, + DataMap: &sync.Map{}, + CreateTime: time.Now().UnixMilli(), + TokenSignList: make([]*TokenSign, 0), + } +} + +func NewSyncSession(id string, sessionType string, loginId string) *SyncSession { + return &SyncSession{ + Id: id, + Type: sessionType, + LoginId: loginId, + CreateTime: time.Now().UnixMilli(), + DataMap: &sync.Map{}, + TokenSignList: make([]*TokenSign, 0), + } +} + +// GetFilterTokenSign filter by TokenSign.Device from all TokenSign +func (s *SyncSession) GetFilterTokenSign(device string) *list.List { + if device == "" { + return s.GetTokenSignListCopy() + } + copyList := list.New() + for _, tokenSign := range s.TokenSignList { + if tokenSign.Device == device { + copyList.PushBack(tokenSign) + } + } + return copyList +} + +// GetTokenSignListCopy find all TokenSign +func (s *SyncSession) GetTokenSignListCopy() *list.List { + copyList := list.New() + for _, tokenSign := range s.TokenSignList { + copyList.PushBack(tokenSign) + } + return copyList +} + +// GetTokenSign find TokenSign by TokenSign.Value +func (s *SyncSession) GetTokenSign(tokenValue string) *TokenSign { + if tokenValue == "" { + return nil + } + for _, tokenSign := range s.TokenSignList { + if tokenSign.Value == tokenValue { + return tokenSign + } + } + return nil +} + +// AddTokenSign add TokenSign +func (s *SyncSession) AddTokenSign(sign *TokenSign) { + if s.GetTokenSign(sign.Value) != nil { + return + } + s.TokenSignList = append(s.TokenSignList, sign) +} + +// RemoveTokenSign remove TokenSign by TokenSign.Value +func (s *SyncSession) RemoveTokenSign(tokenValue string) bool { + if tokenValue == "" { + return false + } + for i, tokenSign := range s.TokenSignList { + if tokenSign.Value == tokenValue { + // delete + s.RemoveTokenSignByIndex(i) + return true + } + } + return true +} + +// RemoveTokenSignByIndex delete by index +func (s *SyncSession) RemoveTokenSignByIndex(i int) { + s.TokenSignList = append(s.TokenSignList[:i], s.TokenSignList[i+1:]...) +} + +// GetLastTokenByDevice get TokenSign.Value by device +func (s *SyncSession) GetLastTokenByDevice(device string) string { + if device == "" { + return "" + } + tokenSignList := s.GetFilterTokenSign(device) + if tokenSign, ok := tokenSignList.Back().Value.(*TokenSign); ok && tokenSign.Device == device { + return tokenSign.Value + } + return "" +} + +// TokenSignSize get tokenSign size +func (s *SyncSession) TokenSignSize() int { + return len(s.TokenSignList) +} + +// Json return json string +func (s *SyncSession) Json() string { + myStruct := &Session{ + Id: s.Id, + Type: s.Type, + LoginType: s.LoginType, + LoginId: s.LoginId, + Token: s.Token, + CreateTime: s.CreateTime, + TokenSignList: s.TokenSignList, + DataMap: make(map[string]interface{}), + } + + s.DataMap.Range(func(key, value any) bool { + myStruct.DataMap[fmt.Sprintf("%v", key)] = value + return true + }) + + b, err := json.Marshal(myStruct) + if err != nil { + return "" + } + return string(b) +} + +// UnmarshalBytes convert bytes to SyncSession +func (s *SyncSession) UnmarshalBytes(jsonByte []byte) (*SyncSession, error) { + return JsonByteToSyncSession(jsonByte) +} + +// UnmarshalStr convert string to SyncSession +func (s *SyncSession) UnmarshalStr(jsonStr string) (*SyncSession, error) { + return JsonToSyncSession(jsonStr) +} + +// Get returns data from DataMap +func (s *SyncSession) Get(key string) interface{} { + value, ok := s.DataMap.Load(key) + if !ok { + return nil + } + return value +} + +func (s *SyncSession) Set(key string, obj interface{}) { + s.DataMap.Store(key, obj) +} + +// GetOrSet returns the existing value for the key if present. +// Otherwise, it stores and returns the given value. +// The loaded result is true if the value was loaded, false if stored. +func (s *SyncSession) GetOrSet(key string, obj interface{}) (interface{}, bool) { + return s.DataMap.LoadOrStore(key, obj) +}