files.*fileSystemRepository.load   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nop 0
dl 0
loc 20
rs 9.7
c 0
b 0
f 0
1
package files
2
3
import (
4
	"encoding/gob"
5
	"fmt"
6
	"io/ioutil"
7
	"os"
8
	"path/filepath"
9
10
	"github.com/rchargel/hdfs-explorer/base"
11
	"github.com/rchargel/hdfs-explorer/log"
12
)
13
14
// FileSystemRepository is used to load/store/find all of the previously configured FileSystems.
15
type FileSystemRepository interface {
16
	List() ([]FileSystem, error)
17
	FindByName(name string) (*FileSystem, error)
18
	Remove(name string) error
19
	Store(fileSystem FileSystem) error
20
}
21
22
type fileSystemRepository struct {
23
	path string
24
}
25
26
func (f *fileSystemRepository) List() ([]FileSystem, error) {
27
	return f.load()
28
}
29
30
func (f *fileSystemRepository) FindByName(name string) (*FileSystem, error) {
31
	if values, err := f.load(); err == nil {
32
		for _, value := range values {
33
			if value.Name == name {
34
				return &value, nil
35
			}
36
		}
37
	} else {
38
		return nil, err
39
	}
40
	return nil, fmt.Errorf("Could not find a FileSystem named %v", name)
41
}
42
43
func (f *fileSystemRepository) Remove(name string) error {
44
	if values, err := f.load(); err == nil {
45
		saved := make([]FileSystem, 0)
46
		for _, value := range values {
47
			if value.Name != name {
48
				saved = append(saved, value)
49
			}
50
		}
51
52
		return f.save(saved)
53
	} else {
54
		return err
55
	}
56
}
57
58
func (f *fileSystemRepository) Store(fileSystem FileSystem) error {
59
	log.Info.Printf("Storing New File System %v", fileSystem.Name)
60
61
	if values, err := f.load(); err == nil {
62
		saved := make([]FileSystem, 0)
63
		added := false
64
		for _, value := range values {
65
			if value.Name == fileSystem.Name {
66
				saved = append(saved, fileSystem)
67
				added = true
68
			} else {
69
				saved = append(saved, value)
70
			}
71
		}
72
		if !added {
73
			saved = append(saved, fileSystem)
74
		}
75
		return f.save(saved)
76
	} else {
77
		return err
78
	}
79
}
80
81
func (f *fileSystemRepository) load() ([]FileSystem, error) {
82
	fileSystems := make([]FileSystem, 0)
83
84
	if file, err := os.Open(f.path); err == nil {
85
		defer file.Close()
86
		dec := gob.NewDecoder(file)
87
		fs := &FileSystem{}
88
		for {
89
			err := dec.Decode(fs)
90
			if err != nil {
91
				break
92
			}
93
94
			fileSystems = append(fileSystems, *fs)
95
		}
96
	} else {
97
		return nil, err
98
	}
99
100
	return fileSystems, nil
101
}
102
103
func (f *fileSystemRepository) save(fileSystems []FileSystem) error {
104
	if tmp, err := ioutil.TempFile("", "filerepo*.tmp"); err == nil {
105
		enc := gob.NewEncoder(tmp)
106
		for _, value := range fileSystems {
107
			err = enc.Encode(value)
108
			if err != nil {
109
				return err
110
			}
111
		}
112
		tmp.Close()
113
		os.Remove(f.path)
114
		return os.Rename(tmp.Name(), f.path)
115
	} else {
116
		return err
117
	}
118
}
119
120
// GetFileSystemRepository loads an instance of the FileSystemRepository interface.
121
// This call will default to reading the data from $HOME/.fsrepo/fs.repo.
122
func GetFileSystemRepository() (FileSystemRepository, error) {
123
	repoFile := filepath.Join(base.HomeDir, "fs.repo")
124
	return GetFileSystemRepositoryFromPath(repoFile)
125
}
126
127
// GetFileSystemRepositoryFromPath loads an instance of the FileSystemRepository found at a specified
128
// location.
129
func GetFileSystemRepositoryFromPath(path string) (FileSystemRepository, error) {
130
	if file, err := GetOrCreateFile(path); err == nil {
131
		file.Close()
132
		return &fileSystemRepository{path}, nil
133
	} else {
134
		return nil, err
135
	}
136
}
137