Documentation
¶
Overview ¶
----------------------------------------------------------------------------- THIS IS UNABRIDGED DOCUMENTATION, PLEASE SEE THE README.md in the project root for more details. -----------------------------------------------------------------------------
package configdb provides convenient access methods to configuration stored as JSON or YAML.
Let's start with a simple YAML file config.yml:
development: database: host: localhost users: - name: calvin password: yukon - name: hobbes password: tuna production: database: host: 192.168.1.1
We can parse it using ParseYaml(), which will return a *Config instance on success:
c1 := (&config.InitContext{}).FromFile("config.yaml").Load().U()
An equivalent JSON configuration could be built using ParseJson():
c1 := (&config.InitContext{}).FromFile("config.json").Load().U()
From now, we can retrieve configuration values using a path in dotted notation:
// "localhost" host := c1.DotP("development.database.host").String() // or... // "192.168.1.1" host := c1.DotP("production.database.host").String()
Besides String(), other types can be fetched directly: Bool(), Float64(), Int(), Map() and List(). All these methods will issue an error if the path doesn't exist, or the value doesn't match or can't be converted to the requested type.
A nested configuration can be fetched using DotP(). Here we get a new *Config instance with a subset of the configuration:
c2 := c2.DotP("development")
Then the inner values are fetched relatively to the subset:
// "localhost" host := c2.DotP("database.host").String()
For lists, the dotted path must use an index to refer to a specific value. To retrieve the information from a user stored in the configuration above:
// map[string]interface{}{ ... } user1 := c1.DotP("development.users.0").Map() // map[string]interface{}{ ... } user2 := c1.DotP("development.users.1").Map() // or... // "calvin" name1 := c1.DotP("development.users.0.name").String() // "hobbes" name2 := c1.DotP("development.users.1.name").String()
Index ¶
- Constants
- Variables
- func Extend_v2_any(a1 any, a2 any) any
- func PrintMemUsage()
- func RenderJson(c interface{}) (string, error)
- func RenderYaml(c interface{}) (string, error)
- func SplitPathToParts(key string) []string
- func TranslateEnvs_KeySuffix(s string) string
- type Command
- type CurrPath
- type ExpressionFailure
- type ISerkDataAPI
- type InitContext
- func (ic *InitContext) Err(err *error) *InitContext
- func (ic *InitContext) FromBytes(data []byte, hashes ...string) *InitContext
- func (ic *InitContext) FromFile(fileName string, hashes ...string) *InitContext
- func (ic *InitContext) Load() *Node
- func (ic *InitContext) LoadWithParenting() (result *Node)
- func (ic *InitContext) Ok(ok *bool) *InitContext
- func (ic *InitContext) WithLogger(logger *zerolog.Logger) *InitContext
- type Location
- type MsgCmd
- type MsgFlushSignal
- type NewSource_Options
- type Node
- func (c *Node) Args(args ...string) *Node
- func (c *Node) At(pathParts ...string) *Node
- func (c *Node) Bool(defaultValueFunc ...func() bool) bool
- func (c *Node) BytesFromBase64(defaultValueFunc ...func() []byte) []byte
- func (c *Node) ChildCopy() (c2 *Node)
- func (c *Node) DDash()
- func (c *Node) DotP(path string) *Node
- func (c *Node) Duration(defaultValueFunc ...func() time.Duration) time.Duration
- func (c *Node) Err(err *error) (c2 *Node)
- func (c *Node) ErrOk() *Node
- func (c *Node) ExtendBy(c2 *Node) *Node
- func (c *Node) ExtendByEnvsV2_WithPrefix(prefix string, transformerFuncs ...func(s string) string)
- func (c *Node) ExtendByEnvs_WithPrefix(prefix string) *Node
- func (c *Node) ExtendBy_v2(c2 *Node) *Node
- func (c *Node) Flag() *Node
- func (c *Node) Float64(defaultValueFunc ...func() float64) float64
- func (c *Node) GetCurrentLocationPlusPath(pathParts ...string) (path []string)
- func (c *Node) Int(defaultValueFunc ...func() int) int
- func (c *Node) List(defaultValueFunc ...func() []any) []any
- func (c *Node) ListDuration(defaultValueFunc ...func() []time.Duration) []time.Duration
- func (c *Node) ListFloat64(defaultValueFunc ...func() []float64) []float64
- func (c *Node) ListInt(defaultValueFunc ...func() []int) []int
- func (c *Node) ListNode() []*Node
- func (c *Node) ListString(defaultValueFunc ...func() []string) []string
- func (c *Node) ListTime(defaultValueFunc ...func() []time.Time) []time.Time
- func (c *Node) Map(defaultValueFunc ...func() map[string]any) map[string]any
- func (c *Node) MapBool(defaultValueFunc ...func() map[string]bool) map[string]bool
- func (c *Node) MapDuration(defaultValueFunc ...func() map[string]time.Duration) map[string]time.Duration
- func (c *Node) MapFloat64(defaultValueFunc ...func() map[string]float64) map[string]float64
- func (c *Node) MapInt(defaultValueFunc ...func() map[string]int) map[string]int
- func (c *Node) MapNode() map[string]*Node
- func (c *Node) MapString(defaultValueFunc ...func() map[string]string) map[string]string
- func (c *Node) MapTime(defaultValueFunc ...func() map[string]time.Time) map[string]time.Time
- func (c *Node) Ok(okRef *bool) (c2 *Node)
- func (c *Node) P(pathParts ...string) *Node
- func (c *Node) PP(path string) *Node
- func (c *Node) PrintJson(tag string)
- func (c *Node) RaisableWithTag(tag string) (c2 *Node)
- func (c *Node) Set(pathParts []string, v interface{})
- func (c *Node) Set_ThreadUnsafe(pathParts []string, v interface{})
- func (c *Node) SlashP(path string) *Node
- func (c *Node) String(defaultValueFunc ...func() string) string
- func (c *Node) TheIsa()
- func (c *Node) Time(defaultValueFunc ...func() time.Time) time.Time
- func (c *Node) U() (c2 *Node)
- func (c *Node) UnU() (c2 *Node)
- type SerkAdapterAsync
- type SerkAdapterSync
- type Source
- type TreeTraversalContext
Constants ¶
const ( ExpressionStatus_0_Norm = iota ExpressionStatus_1_Failed ExpressionStatus_2_DefaultCallbackAlreadyUsedOnce )
Variables ¶
var ErrMsg_MultipleCallbackWithoutPriorErrOk = "default value callback used multiple times, without prior ErrOk()"
var ReEnvs01 = regexp.MustCompile(`\W`)
Functions ¶
func PrintMemUsage ¶
func PrintMemUsage()
PrintMemUsage outputs the current, total and OS memory being used. As well as the number of garage collection cycles completed.
func RenderJson ¶
RenderJson renders a JSON configuration.
func RenderYaml ¶
RenderYaml renders a YAML configuration.
func SplitPathToParts ¶
func TranslateEnvs_KeySuffix ¶
Does this replacements:
p__ -> "." (point) d__ -> "-" (dash) u__ -> "__" (underscore) D__ -> "$" (dollar) A__ -> "@" (at)
For example, the line "Somethingp__superd__duperp__D__isa" will become "Something.super-duper.$isa". Because the key is located at the end of words, this makes minimal possible impact on readability.
Types ¶
type ExpressionFailure ¶
type ExpressionFailure int
type InitContext ¶
type InitContext struct { CurrentFileName string SourceHashesRequired []string SourceHashesActual []string Data []byte Logger *zerolog.Logger ErrPtr *error OkPtr *bool }
func (*InitContext) Err ¶
func (ic *InitContext) Err(err *error) *InitContext
func (*InitContext) FromBytes ¶
func (ic *InitContext) FromBytes(data []byte, hashes ...string) *InitContext
func (*InitContext) FromFile ¶
func (ic *InitContext) FromFile(fileName string, hashes ...string) *InitContext
func (*InitContext) Load ¶
func (ic *InitContext) Load() *Node
func (*InitContext) LoadWithParenting ¶
func (ic *InitContext) LoadWithParenting() (result *Node)
func (*InitContext) Ok ¶
func (ic *InitContext) Ok(ok *bool) *InitContext
func (*InitContext) WithLogger ¶
func (ic *InitContext) WithLogger(logger *zerolog.Logger) *InitContext
type MsgFlushSignal ¶
type MsgFlushSignal struct {
ChDown chan struct{}
}
type NewSource_Options ¶
type Node ¶
type Node struct { Sub any OkPtr *bool ErrPtr *error ExpressionStatus ExpressionFailure RTag string Source *Source `json:"-"` InitContext *InitContext `json:"-"` // contains filtered or unexported fields }
Node represents a configuration with convenient access methods.
func (*Node) BytesFromBase64 ¶
func (*Node) Err ¶
Attaches an err error variable to the expression, by reference. Make sure to reset it to nil when reusing between expressions.
func (*Node) ErrOk ¶
Resets any errors, accumulated in previous expressions on this Config object. Sets Ok=true, Err=nil, ExpressionStatus=0_Norm, if any
func (*Node) ExtendBy ¶
ExtendBy() extends current config with another config: i.e. all values from another config are added to the current config, and overwritten with new values if already present. It implements limited prototype-based inheritance. It does not add elements, if not present in the prototype. Note that if you extend with different structure type you will get an error. See: `.Set()` method for details.
func (*Node) ExtendByEnvsV2_WithPrefix ¶
Unlike the ExtendByEnvs_WithPrefix(), this function allows to create new nodes in the config, based on the envs. It scans all envs matching the specified prefix, then strips the prefix, then what is left is used as a valid dot-path as is. For example, if the prefix was PRFX, and you specify an env var "PRFX_asd-qwe.zxc.123", then this variable will set, and create if necessary, the node at path "asd-qwe.zxc.123". If such names are supported in your OS is up to you, but see the https://stackoverflow.com/questions/2821043/allowed-characters-in-linux-environment-variable-names. Update: As it turns out, the OS may support it, but the bash didn't, and so you can use it. To solve this issue, I am adding a transformation callback, which can additionally transform the path string, so you can avoid using non-alphanumerics in env names. See also the TranslateEnvs_KeySuffix().
func (*Node) ExtendByEnvs_WithPrefix ¶
Fetch data from system env using prefix, based on existing config keys. The algorithm: for all possible paths in config do { join by "_"; make uppercase; remove all punctuation except "_"; add prefix; lookup if there is an env with that name; if it is - get its value and set to the config at the path}. VERY IMPORTANT USAGE NOTE: this can override what is already present in the config, but it cannot create new things, which were not in the configdb.
In case of OS environment all existing at the moment of parsing keys will be scanned in OS environment, but in uppercase and the separator will be `_` instead of a `.`. If EnvPrefix() is used the given prefix will be used to lookup the environment variable, e.g PREFIX_FOO_BAR will set foo.bar. In case of flags separator will be `-`. In case of command line arguments possible to use regular dot notation syntax for all keys. For see existing keys we can run application with `-h`.
func (*Node) ExtendBy_v2 ¶
ExtendBy() extends current config with another config: i.e. all values from another config are added to the current config, and overwritten with new values if already present. It implements prototype-based inheritance.
func (*Node) GetCurrentLocationPlusPath ¶
func (*Node) ListDuration ¶
func (*Node) ListFloat64 ¶
func (*Node) ListString ¶
func (*Node) MapDuration ¶
func (*Node) MapFloat64 ¶
func (*Node) Ok ¶
Attaches a ok bool variable to the expression, by reference, with it's current value. Failures in subsequent operations may set it to false only, so make sure its current state is true.
func (*Node) P ¶
Traverses the struct down the path. P() does not create a path, if it didn't exist. So, if used before Set(), it will take you as far as there is something, not farther.
func (*Node) RaisableWithTag ¶
Useful if you want to work with exceptions
func (*Node) Set ¶
Sets a nested config according to a path, relative from current location. Without a Source object set, acts as a by-pass to the NonThreadSafe_Set(). If you don't want to specify path, and just want to use it from current location, then invoke with nil path, c.Set(nil, value) It is totally asynchronous, and it's effect is somewhat delayed. Use explicit flush signal if you want to synchronize explicitly. P() does not create a path, if it didn't exist. So, if used before Set(), it will take you as far as there is something, not farther.
func (*Node) Set_ThreadUnsafe ¶
Sets a nested config according to a path, relative from current location. If you don't want to specify path, and just want to use it from current location, then invoke with nil path.
type SerkAdapterAsync ¶
type SerkAdapterAsync struct {
CS *Source
}
thread-safe
func (*SerkAdapterAsync) Test ¶
func (a *SerkAdapterAsync) Test()
type SerkAdapterSync ¶
type SerkAdapterSync struct {
C *Node
}
thread-unsafe
func (*SerkAdapterSync) Test ¶
func (a *SerkAdapterSync) Test()
type Source ¶
type Source struct { RootNode *Node ChCmd chan *MsgCmd ChFlushSignal chan *MsgFlushSignal Opts *NewSource_Options }
func NewSource ¶
func NewSource(f ...func(opts *NewSource_Options)) (s *Source)
type TreeTraversalContext ¶
type TreeTraversalContext struct {
// contains filtered or unexported fields
}