github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/environs/configstore/mem.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package configstore 5 6 import ( 7 "fmt" 8 "sync" 9 10 "github.com/juju/errors" 11 ) 12 13 type memStore struct { 14 mu sync.Mutex 15 envs map[string]*memInfo 16 } 17 18 type memInfo struct { 19 store *memStore 20 name string 21 environInfo 22 } 23 24 // clone returns a copy of the given environment info, isolated 25 // from the store itself. 26 func (info *memInfo) clone() *memInfo { 27 // Note that none of the Set* methods ever set fields inside 28 // references, which makes this OK to do. 29 info1 := *info 30 newAttrs := make(map[string]interface{}) 31 for name, attr := range info.EnvInfo.Config { 32 newAttrs[name] = attr 33 } 34 info1.EnvInfo.Config = newAttrs 35 info1.created = false 36 return &info1 37 } 38 39 // NewMem returns a ConfigStorage implementation that 40 // stores configuration in memory. 41 func NewMem() Storage { 42 return &memStore{ 43 envs: make(map[string]*memInfo), 44 } 45 } 46 47 // CreateInfo implements Storage.CreateInfo. 48 func (m *memStore) CreateInfo(envName string) (EnvironInfo, error) { 49 m.mu.Lock() 50 defer m.mu.Unlock() 51 if m.envs[envName] != nil { 52 return nil, ErrEnvironInfoAlreadyExists 53 } 54 info := &memInfo{ 55 store: m, 56 name: envName, 57 } 58 info.created = true 59 m.envs[envName] = info.clone() 60 return info, nil 61 } 62 63 // ReadInfo implements Storage.ReadInfo. 64 func (m *memStore) ReadInfo(envName string) (EnvironInfo, error) { 65 m.mu.Lock() 66 defer m.mu.Unlock() 67 info := m.envs[envName] 68 if info != nil { 69 return info.clone(), nil 70 } 71 return nil, errors.NotFoundf("environment %q", envName) 72 } 73 74 // Location implements EnvironInfo.Location. 75 func (info *memInfo) Location() string { 76 return "memory" 77 } 78 79 // Write implements EnvironInfo.Write. 80 func (info *memInfo) Write() error { 81 m := info.store 82 m.mu.Lock() 83 defer m.mu.Unlock() 84 info.initialized = true 85 m.envs[info.name] = info.clone() 86 return nil 87 } 88 89 // Destroy implements EnvironInfo.Destroy. 90 func (info *memInfo) Destroy() error { 91 m := info.store 92 m.mu.Lock() 93 defer m.mu.Unlock() 94 if m.envs[info.name] == nil { 95 return fmt.Errorf("environment info has already been removed") 96 } 97 delete(m.envs, info.name) 98 return nil 99 }