1
0

properties.go 2.6 KB

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