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  }