1package logical
2
3import (
4	"context"
5	"sync"
6
7	"github.com/hashicorp/vault/sdk/physical"
8	"github.com/hashicorp/vault/sdk/physical/inmem"
9)
10
11// InmemStorage implements Storage and stores all data in memory. It is
12// basically a straight copy of physical.Inmem, but it prevents backends from
13// having to load all of physical's dependencies (which are legion) just to
14// have some testing storage.
15type InmemStorage struct {
16	underlying physical.Backend
17	once       sync.Once
18}
19
20func (s *InmemStorage) Get(ctx context.Context, key string) (*StorageEntry, error) {
21	s.once.Do(s.init)
22
23	entry, err := s.underlying.Get(ctx, key)
24	if err != nil {
25		return nil, err
26	}
27	if entry == nil {
28		return nil, nil
29	}
30	return &StorageEntry{
31		Key:      entry.Key,
32		Value:    entry.Value,
33		SealWrap: entry.SealWrap,
34	}, nil
35}
36
37func (s *InmemStorage) Put(ctx context.Context, entry *StorageEntry) error {
38	s.once.Do(s.init)
39
40	return s.underlying.Put(ctx, &physical.Entry{
41		Key:      entry.Key,
42		Value:    entry.Value,
43		SealWrap: entry.SealWrap,
44	})
45}
46
47func (s *InmemStorage) Delete(ctx context.Context, key string) error {
48	s.once.Do(s.init)
49
50	return s.underlying.Delete(ctx, key)
51}
52
53func (s *InmemStorage) List(ctx context.Context, prefix string) ([]string, error) {
54	s.once.Do(s.init)
55
56	return s.underlying.List(ctx, prefix)
57}
58
59func (s *InmemStorage) Underlying() *inmem.InmemBackend {
60	s.once.Do(s.init)
61
62	return s.underlying.(*inmem.InmemBackend)
63}
64
65func (s *InmemStorage) init() {
66	s.underlying, _ = inmem.NewInmem(nil, nil)
67}
68