github.com/astaxie/beego@v1.12.3/session/ssdb/sess_ssdb.go (about)

     1  package ssdb
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"strconv"
     7  	"strings"
     8  	"sync"
     9  
    10  	"github.com/astaxie/beego/session"
    11  	"github.com/ssdb/gossdb/ssdb"
    12  )
    13  
    14  var ssdbProvider = &Provider{}
    15  
    16  // Provider holds ssdb client and configs
    17  type Provider struct {
    18  	client      *ssdb.Client
    19  	host        string
    20  	port        int
    21  	maxLifetime int64
    22  }
    23  
    24  func (p *Provider) connectInit() error {
    25  	var err error
    26  	if p.host == "" || p.port == 0 {
    27  		return errors.New("SessionInit First")
    28  	}
    29  	p.client, err = ssdb.Connect(p.host, p.port)
    30  	return err
    31  }
    32  
    33  // SessionInit init the ssdb with the config
    34  func (p *Provider) SessionInit(maxLifetime int64, savePath string) error {
    35  	p.maxLifetime = maxLifetime
    36  	address := strings.Split(savePath, ":")
    37  	p.host = address[0]
    38  
    39  	var err error
    40  	if p.port, err = strconv.Atoi(address[1]); err != nil {
    41  		return err
    42  	}
    43  	return p.connectInit()
    44  }
    45  
    46  // SessionRead return a ssdb client session Store
    47  func (p *Provider) SessionRead(sid string) (session.Store, error) {
    48  	if p.client == nil {
    49  		if err := p.connectInit(); err != nil {
    50  			return nil, err
    51  		}
    52  	}
    53  	var kv map[interface{}]interface{}
    54  	value, err := p.client.Get(sid)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	if value == nil || len(value.(string)) == 0 {
    59  		kv = make(map[interface{}]interface{})
    60  	} else {
    61  		kv, err = session.DecodeGob([]byte(value.(string)))
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  	}
    66  	rs := &SessionStore{sid: sid, values: kv, maxLifetime: p.maxLifetime, client: p.client}
    67  	return rs, nil
    68  }
    69  
    70  // SessionExist judged whether sid is exist in session
    71  func (p *Provider) SessionExist(sid string) bool {
    72  	if p.client == nil {
    73  		if err := p.connectInit(); err != nil {
    74  			panic(err)
    75  		}
    76  	}
    77  	value, err := p.client.Get(sid)
    78  	if err != nil {
    79  		panic(err)
    80  	}
    81  	if value == nil || len(value.(string)) == 0 {
    82  		return false
    83  	}
    84  	return true
    85  }
    86  
    87  // SessionRegenerate regenerate session with new sid and delete oldsid
    88  func (p *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
    89  	//conn.Do("setx", key, v, ttl)
    90  	if p.client == nil {
    91  		if err := p.connectInit(); err != nil {
    92  			return nil, err
    93  		}
    94  	}
    95  	value, err := p.client.Get(oldsid)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	var kv map[interface{}]interface{}
   100  	if value == nil || len(value.(string)) == 0 {
   101  		kv = make(map[interface{}]interface{})
   102  	} else {
   103  		kv, err = session.DecodeGob([]byte(value.(string)))
   104  		if err != nil {
   105  			return nil, err
   106  		}
   107  		_, err = p.client.Del(oldsid)
   108  		if err != nil {
   109  			return nil, err
   110  		}
   111  	}
   112  	_, e := p.client.Do("setx", sid, value, p.maxLifetime)
   113  	if e != nil {
   114  		return nil, e
   115  	}
   116  	rs := &SessionStore{sid: sid, values: kv, maxLifetime: p.maxLifetime, client: p.client}
   117  	return rs, nil
   118  }
   119  
   120  // SessionDestroy destroy the sid
   121  func (p *Provider) SessionDestroy(sid string) error {
   122  	if p.client == nil {
   123  		if err := p.connectInit(); err != nil {
   124  			return err
   125  		}
   126  	}
   127  	_, err := p.client.Del(sid)
   128  	return err
   129  }
   130  
   131  // SessionGC not implemented
   132  func (p *Provider) SessionGC() {
   133  }
   134  
   135  // SessionAll not implemented
   136  func (p *Provider) SessionAll() int {
   137  	return 0
   138  }
   139  
   140  // SessionStore holds the session information which stored in ssdb
   141  type SessionStore struct {
   142  	sid         string
   143  	lock        sync.RWMutex
   144  	values      map[interface{}]interface{}
   145  	maxLifetime int64
   146  	client      *ssdb.Client
   147  }
   148  
   149  // Set the key and value
   150  func (s *SessionStore) Set(key, value interface{}) error {
   151  	s.lock.Lock()
   152  	defer s.lock.Unlock()
   153  	s.values[key] = value
   154  	return nil
   155  }
   156  
   157  // Get return the value by the key
   158  func (s *SessionStore) Get(key interface{}) interface{} {
   159  	s.lock.Lock()
   160  	defer s.lock.Unlock()
   161  	if value, ok := s.values[key]; ok {
   162  		return value
   163  	}
   164  	return nil
   165  }
   166  
   167  // Delete the key in session store
   168  func (s *SessionStore) Delete(key interface{}) error {
   169  	s.lock.Lock()
   170  	defer s.lock.Unlock()
   171  	delete(s.values, key)
   172  	return nil
   173  }
   174  
   175  // Flush delete all keys and values
   176  func (s *SessionStore) Flush() error {
   177  	s.lock.Lock()
   178  	defer s.lock.Unlock()
   179  	s.values = make(map[interface{}]interface{})
   180  	return nil
   181  }
   182  
   183  // SessionID return the sessionID
   184  func (s *SessionStore) SessionID() string {
   185  	return s.sid
   186  }
   187  
   188  // SessionRelease Store the keyvalues into ssdb
   189  func (s *SessionStore) SessionRelease(w http.ResponseWriter) {
   190  	b, err := session.EncodeGob(s.values)
   191  	if err != nil {
   192  		return
   193  	}
   194  	s.client.Do("setx", s.sid, string(b), s.maxLifetime)
   195  }
   196  
   197  func init() {
   198  	session.Register("ssdb", ssdbProvider)
   199  }