|
|
|
|
@ -29,18 +29,22 @@ import ( |
|
|
|
|
|
|
|
|
|
// MysqlStore represents a mysql session store implementation.
|
|
|
|
|
type MysqlStore struct { |
|
|
|
|
c *sql.DB |
|
|
|
|
sid string |
|
|
|
|
lock sync.RWMutex |
|
|
|
|
data map[interface{}]interface{} |
|
|
|
|
c *sql.DB |
|
|
|
|
sid string |
|
|
|
|
lock sync.RWMutex |
|
|
|
|
data map[interface{}]interface{} |
|
|
|
|
expiry int64 |
|
|
|
|
dirty bool |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// NewMysqlStore creates and returns a mysql session store.
|
|
|
|
|
func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}) *MysqlStore { |
|
|
|
|
func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}, expiry int64) *MysqlStore { |
|
|
|
|
return &MysqlStore{ |
|
|
|
|
c: c, |
|
|
|
|
sid: sid, |
|
|
|
|
data: kv, |
|
|
|
|
c: c, |
|
|
|
|
sid: sid, |
|
|
|
|
data: kv, |
|
|
|
|
expiry: expiry, |
|
|
|
|
dirty: false, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -50,6 +54,7 @@ func (s *MysqlStore) Set(key, val interface{}) error { |
|
|
|
|
defer s.lock.Unlock() |
|
|
|
|
|
|
|
|
|
s.data[key] = val |
|
|
|
|
s.dirty = true |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -67,6 +72,7 @@ func (s *MysqlStore) Delete(key interface{}) error { |
|
|
|
|
defer s.lock.Unlock() |
|
|
|
|
|
|
|
|
|
delete(s.data, key) |
|
|
|
|
s.dirty = true |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -77,13 +83,20 @@ func (s *MysqlStore) ID() string { |
|
|
|
|
|
|
|
|
|
// Release releases resource and save data to provider.
|
|
|
|
|
func (s *MysqlStore) Release() error { |
|
|
|
|
newExpiry := time.Now().Unix() |
|
|
|
|
if !s.dirty && (s.expiry+60) >= newExpiry { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
data, err := session.EncodeGob(s.data) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_, err = s.c.Exec("UPDATE session SET data=?, expiry=? WHERE `key`=?", |
|
|
|
|
data, time.Now().Unix(), s.sid) |
|
|
|
|
data, newExpiry, s.sid) |
|
|
|
|
s.dirty = false |
|
|
|
|
s.expiry = newExpiry |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -93,6 +106,7 @@ func (s *MysqlStore) Flush() error { |
|
|
|
|
defer s.lock.Unlock() |
|
|
|
|
|
|
|
|
|
s.data = make(map[interface{}]interface{}) |
|
|
|
|
s.dirty = true |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -117,11 +131,12 @@ func (p *MysqlProvider) Init(expire int64, connStr string) (err error) { |
|
|
|
|
|
|
|
|
|
// Read returns raw session store by session ID.
|
|
|
|
|
func (p *MysqlProvider) Read(sid string) (session.RawStore, error) { |
|
|
|
|
expiry := time.Now().Unix() |
|
|
|
|
var data []byte |
|
|
|
|
err := p.c.QueryRow("SELECT data FROM session WHERE `key`=?", sid).Scan(&data) |
|
|
|
|
err := p.c.QueryRow("SELECT data,expiry FROM session WHERE `key`=?", sid).Scan(&data, &expiry) |
|
|
|
|
if err == sql.ErrNoRows { |
|
|
|
|
_, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)", |
|
|
|
|
sid, "", time.Now().Unix()) |
|
|
|
|
sid, "", expiry) |
|
|
|
|
} |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
@ -137,7 +152,7 @@ func (p *MysqlProvider) Read(sid string) (session.RawStore, error) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return NewMysqlStore(p.c, sid, kv), nil |
|
|
|
|
return NewMysqlStore(p.c, sid, kv, expiry), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Exist returns true if session with given ID exists.
|
|
|
|
|
|