diff options
author | Alexander NeonXP Kiryukhin <i@neonxp.ru> | 2024-07-28 19:32:33 +0300 |
---|---|---|
committer | Alexander NeonXP Kiryukhin <i@neonxp.ru> | 2024-07-28 19:32:33 +0300 |
commit | 18a9096684ab0b1468a08d442d38b7b675d94810 (patch) | |
tree | 16e335e56ac0bf7986c3fbcd924f2ac0e00106f8 /session | |
parent | 25160ef84704c0f4ef6e8c6cf2e282e216701139 (diff) |
Diffstat (limited to 'session')
-rw-r--r-- | session/bbolt/bbolt.go | 61 | ||||
-rw-r--r-- | session/bbolt/go.mod | 7 | ||||
-rw-r--r-- | session/bbolt/go.sum | 4 | ||||
-rw-r--r-- | session/memstore.go | 25 | ||||
-rw-r--r-- | session/store.go | 17 |
5 files changed, 114 insertions, 0 deletions
diff --git a/session/bbolt/bbolt.go b/session/bbolt/bbolt.go new file mode 100644 index 0000000..8e55d25 --- /dev/null +++ b/session/bbolt/bbolt.go @@ -0,0 +1,61 @@ +package bbolt + +import ( + "bytes" + "context" + "encoding/gob" + "log/slog" + + "go.etcd.io/bbolt" + "go.neonxp.ru/middleware/session" +) + +func New(db *bbolt.DB, bucketName []byte) session.Store { + return &Store{ + db: db, + bucketName: bucketName, + } +} + +type Store struct { + db *bbolt.DB + bucketName []byte +} + +func (s *Store) Load(ctx context.Context, sessionID string) session.Value { + v := session.Value{} + err := s.db.View(func(tx *bbolt.Tx) error { + bucket := tx.Bucket(s.bucketName) + if bucket == nil { + // no bucket -- normal situation + return nil + } + vb := bucket.Get([]byte(sessionID)) + if vb == nil { + // no session -- no error + return nil + } + rdr := bytes.NewBuffer(vb) + + return gob.NewDecoder(rdr).Decode(&v) + }) + if err != nil { + slog.WarnContext(ctx, "failed load session", slog.Any("error", err)) + } + return v +} + +func (s *Store) Save(ctx context.Context, sessionID string, value session.Value) error { + return s.db.Update(func(tx *bbolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(s.bucketName) + if err != nil { + return err + } + wrt := bytes.NewBuffer([]byte{}) + if err := gob.NewEncoder(wrt).Encode(value); err != nil { + return err + } + + return bucket.Put([]byte(sessionID), wrt.Bytes()) + }) +} diff --git a/session/bbolt/go.mod b/session/bbolt/go.mod new file mode 100644 index 0000000..f50214b --- /dev/null +++ b/session/bbolt/go.mod @@ -0,0 +1,7 @@ +module gitrepo.ru/neonxp/middleware/session/bbolt + +go 1.22.5 + +require go.etcd.io/bbolt v1.3.10 + +require golang.org/x/sys v0.4.0 // indirect diff --git a/session/bbolt/go.sum b/session/bbolt/go.sum new file mode 100644 index 0000000..3a4cae6 --- /dev/null +++ b/session/bbolt/go.sum @@ -0,0 +1,4 @@ +go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= +go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/session/memstore.go b/session/memstore.go new file mode 100644 index 0000000..97d70a1 --- /dev/null +++ b/session/memstore.go @@ -0,0 +1,25 @@ +package session + +import ( + "context" + "sync" +) + +type MemoryStore struct { + store sync.Map +} + +func (s *MemoryStore) Load(ctx context.Context, sessionID string) Value { + val, ok := s.store.Load(sessionID) + if ok { + return val.(Value) + } + + return Value{} +} + +func (s *MemoryStore) Save(ctx context.Context, sessionID string, value Value) error { + s.store.Store(sessionID, value) + + return nil +} diff --git a/session/store.go b/session/store.go new file mode 100644 index 0000000..adef69a --- /dev/null +++ b/session/store.go @@ -0,0 +1,17 @@ +package session + +import ( + "context" + "errors" +) + +var ( + ErrSessionNotFound = errors.New("session not found") +) + +type Store interface { + Load(ctx context.Context, sessionID string) Value + Save(ctx context.Context, sessionID string, value Value) error +} + +type Value map[string]any |