-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
properties.go
119 lines (99 loc) · 2.61 KB
/
properties.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package conf
import (
"fmt"
"os"
"strconv"
"strings"
"sync"
"github.com/zeromicro/go-zero/core/iox"
)
// PropertyError represents a configuration error message.
type PropertyError struct {
error
message string
}
// Properties interface provides the means to access configuration.
type Properties interface {
GetString(key string) string
SetString(key, value string)
GetInt(key string) int
SetInt(key string, value int)
ToString() string
}
// Properties config is a key/value pair based configuration structure.
type mapBasedProperties struct {
properties map[string]string
lock sync.RWMutex
}
// LoadProperties loads the properties into a properties configuration instance.
// Returns an error that indicates if there was a problem loading the configuration.
func LoadProperties(filename string, opts ...Option) (Properties, error) {
lines, err := iox.ReadTextLines(filename, iox.WithoutBlank(), iox.OmitWithPrefix("#"))
if err != nil {
return nil, err
}
var opt options
for _, o := range opts {
o(&opt)
}
raw := make(map[string]string)
for i := range lines {
pair := strings.Split(lines[i], "=")
if len(pair) != 2 {
// invalid property format
return nil, &PropertyError{
message: fmt.Sprintf("invalid property format: %s", pair),
}
}
key := strings.TrimSpace(pair[0])
value := strings.TrimSpace(pair[1])
if opt.env {
raw[key] = os.ExpandEnv(value)
} else {
raw[key] = value
}
}
return &mapBasedProperties{
properties: raw,
}, nil
}
func (config *mapBasedProperties) GetString(key string) string {
config.lock.RLock()
ret := config.properties[key]
config.lock.RUnlock()
return ret
}
func (config *mapBasedProperties) SetString(key, value string) {
config.lock.Lock()
config.properties[key] = value
config.lock.Unlock()
}
func (config *mapBasedProperties) GetInt(key string) int {
config.lock.RLock()
// default 0
value, _ := strconv.Atoi(config.properties[key])
config.lock.RUnlock()
return value
}
func (config *mapBasedProperties) SetInt(key string, value int) {
config.lock.Lock()
config.properties[key] = strconv.Itoa(value)
config.lock.Unlock()
}
// ToString dumps the configuration internal map into a string.
func (config *mapBasedProperties) ToString() string {
config.lock.RLock()
ret := fmt.Sprintf("%s", config.properties)
config.lock.RUnlock()
return ret
}
// Error returns the error message.
func (configError *PropertyError) Error() string {
return configError.message
}
// NewProperties builds a new properties configuration structure.
func NewProperties() Properties {
return &mapBasedProperties{
properties: make(map[string]string),
}
}