本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
4.9KB

  1. // Copyright 2013 Beego Authors
  2. // Copyright 2014 The Macaron Authors
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  5. // not use this file except in compliance with the License. You may obtain
  6. // a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. // License for the specific language governing permissions and limitations
  14. // under the License.
  15. package session
  16. import (
  17. "strings"
  18. "sync"
  19. "gitea.com/macaron/session"
  20. "github.com/couchbaselabs/go-couchbase"
  21. )
  22. // CouchbaseSessionStore represents a couchbase session store implementation.
  23. type CouchbaseSessionStore struct {
  24. b *couchbase.Bucket
  25. sid string
  26. lock sync.RWMutex
  27. data map[interface{}]interface{}
  28. maxlifetime int64
  29. }
  30. // Set sets value to given key in session.
  31. func (s *CouchbaseSessionStore) Set(key, val interface{}) error {
  32. s.lock.Lock()
  33. defer s.lock.Unlock()
  34. s.data[key] = val
  35. return nil
  36. }
  37. // Get gets value by given key in session.
  38. func (s *CouchbaseSessionStore) Get(key interface{}) interface{} {
  39. s.lock.RLock()
  40. defer s.lock.RUnlock()
  41. return s.data[key]
  42. }
  43. // Delete delete a key from session.
  44. func (s *CouchbaseSessionStore) Delete(key interface{}) error {
  45. s.lock.Lock()
  46. defer s.lock.Unlock()
  47. delete(s.data, key)
  48. return nil
  49. }
  50. // ID returns current session ID.
  51. func (s *CouchbaseSessionStore) ID() string {
  52. return s.sid
  53. }
  54. // Release releases resource and save data to provider.
  55. func (s *CouchbaseSessionStore) Release() error {
  56. defer s.b.Close()
  57. // Skip encoding if the data is empty
  58. if len(s.data) == 0 {
  59. return nil
  60. }
  61. data, err := session.EncodeGob(s.data)
  62. if err != nil {
  63. return err
  64. }
  65. return s.b.Set(s.sid, int(s.maxlifetime), data)
  66. }
  67. // Flush deletes all session data.
  68. func (s *CouchbaseSessionStore) Flush() error {
  69. s.lock.Lock()
  70. defer s.lock.Unlock()
  71. s.data = make(map[interface{}]interface{})
  72. return nil
  73. }
  74. // CouchbaseProvider represents a couchbase session provider implementation.
  75. type CouchbaseProvider struct {
  76. maxlifetime int64
  77. connStr string
  78. pool string
  79. bucket string
  80. b *couchbase.Bucket
  81. }
  82. func (cp *CouchbaseProvider) getBucket() *couchbase.Bucket {
  83. c, err := couchbase.Connect(cp.connStr)
  84. if err != nil {
  85. return nil
  86. }
  87. pool, err := c.GetPool(cp.pool)
  88. if err != nil {
  89. return nil
  90. }
  91. bucket, err := pool.GetBucket(cp.bucket)
  92. if err != nil {
  93. return nil
  94. }
  95. return bucket
  96. }
  97. // Init initializes memory session provider.
  98. // connStr is couchbase server REST/JSON URL
  99. // e.g. http://host:port/, Pool, Bucket
  100. func (p *CouchbaseProvider) Init(maxlifetime int64, connStr string) error {
  101. p.maxlifetime = maxlifetime
  102. configs := strings.Split(connStr, ",")
  103. if len(configs) > 0 {
  104. p.connStr = configs[0]
  105. }
  106. if len(configs) > 1 {
  107. p.pool = configs[1]
  108. }
  109. if len(configs) > 2 {
  110. p.bucket = configs[2]
  111. }
  112. return nil
  113. }
  114. // Read returns raw session store by session ID.
  115. func (p *CouchbaseProvider) Read(sid string) (session.RawStore, error) {
  116. p.b = p.getBucket()
  117. var doc []byte
  118. err := p.b.Get(sid, &doc)
  119. var kv map[interface{}]interface{}
  120. if doc == nil {
  121. kv = make(map[interface{}]interface{})
  122. } else {
  123. kv, err = session.DecodeGob(doc)
  124. if err != nil {
  125. return nil, err
  126. }
  127. }
  128. cs := &CouchbaseSessionStore{b: p.b, sid: sid, data: kv, maxlifetime: p.maxlifetime}
  129. return cs, nil
  130. }
  131. // Exist returns true if session with given ID exists.
  132. func (p *CouchbaseProvider) Exist(sid string) bool {
  133. p.b = p.getBucket()
  134. defer p.b.Close()
  135. var doc []byte
  136. if err := p.b.Get(sid, &doc); err != nil || doc == nil {
  137. return false
  138. } else {
  139. return true
  140. }
  141. }
  142. // Destroy deletes a session by session ID.
  143. func (p *CouchbaseProvider) Destroy(sid string) error {
  144. p.b = p.getBucket()
  145. defer p.b.Close()
  146. p.b.Delete(sid)
  147. return nil
  148. }
  149. // Regenerate regenerates a session store from old session ID to new one.
  150. func (p *CouchbaseProvider) Regenerate(oldsid, sid string) (session.RawStore, error) {
  151. p.b = p.getBucket()
  152. var doc []byte
  153. if err := p.b.Get(oldsid, &doc); err != nil || doc == nil {
  154. p.b.Set(sid, int(p.maxlifetime), "")
  155. } else {
  156. err := p.b.Delete(oldsid)
  157. if err != nil {
  158. return nil, err
  159. }
  160. _, _ = p.b.Add(sid, int(p.maxlifetime), doc)
  161. }
  162. err := p.b.Get(sid, &doc)
  163. if err != nil {
  164. return nil, err
  165. }
  166. var kv map[interface{}]interface{}
  167. if doc == nil {
  168. kv = make(map[interface{}]interface{})
  169. } else {
  170. kv, err = session.DecodeGob(doc)
  171. if err != nil {
  172. return nil, err
  173. }
  174. }
  175. cs := &CouchbaseSessionStore{b: p.b, sid: sid, data: kv, maxlifetime: p.maxlifetime}
  176. return cs, nil
  177. }
  178. // Count counts and returns number of sessions.
  179. func (p *CouchbaseProvider) Count() int {
  180. // FIXME
  181. return 0
  182. }
  183. // GC calls GC to clean expired sessions.
  184. func (p *CouchbaseProvider) GC() {}
  185. func init() {
  186. session.Register("couchbase", &CouchbaseProvider{})
  187. }
上海开阖软件有限公司 沪ICP备12045867号-1