xconfig

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2020 License: MIT Imports: 11 Imported by: 13

README

@UTF-8

Go Report Card GoDoc GolangCI

XConfig for GO v1

Package xconfig loads a configuration file similar to a .ini file, but with some important improvements:

  • The xconfig recognize bool, int, float and Strings, and also collections of values and hierarchical nested sub-config sets.
  • The xconfig is compatible with XDataset to inject and use in templates, database records, etc.
  • You can load more than one file in merge mode or replacing mode in the same config object.
  • You can set and get parameters at any time.
  • You can load the config object based on a file, but also on a string and another object; this way you can serialize, unserialize, transfer by any strem, save or load on database the object, etc.
  • You can also save back the config string with all its comments.

Manuals are available on godoc.org GoDoc

TO DO:

  • Make it thread safe ? (so maybe with a flag to activate it ?)
  • Add Time ? Other types of int32, int64, float32, runes etc ?
  • Merge vs load to load more than 1 file (pending)
  • implement + and :
  • implement Save
  • Add a flag when it's a multiple load to warn a "save"
  • Add error control con Get* for type conversions (if the type is different as expected)
  • Log errors into official log

Version Changes Control

v0.4.0 - 2020-03-29

  • Modulatization (go mod init) and use of xcore/v2
  • Documentation finished
  • Comments into code, corrections to meet golint standards
  • String modified to order printed lines and get a uniform result if the XConfig contains the same data
  • Tests implemented to verify official defined specs

v0.3.0 - 2020-02-11

  • Documentation enhanced, Configuration Syntax Reference added
  • Licence and Tests Added

v0.2.1 - 2020-02-10

  • Documentation enhanced
  • Bug corrected on String and GoString()

v0.2.0 - 2020-02-10

  • Modification to XConfig to meet xcore v1.0.0 (.String and .GoString functions added, .Stringify function removed)

v0.1.0 - 2019-12-06

  • Code formated before sending to github (gofmt -s)

v0.0.9 - 2019-07-12

  • Incode println removed

v0.0.8 - 2019-06-25

  • Added Clone functions to meet xcore.XDatasetDef definition

v0.0.7 - 2019-03-06

  • Added functions of Time to get time data.

v0.0.6 - 2019-02-05

  • Added conversion between types con Get* functions

v0.0.5 - 2019-01-06

  • XConfig object aligned with XDataset with missing set of functions
  • XConfig csn now be injected into an XTemplate

V0.0.4 - 2018-12-21

  • Added GetString, GetInt, GetBool and GetFloat to directly get the known value type (and do not have to convert types)
  • Error corrected on Set (type float added)

V0.0.3 - 2018-12-05

Branch "late-night" added to github

  • Added support for sub-XConfig with entry1.entry2.entry3=xxx

V0.0.2 - 2018-11-27

  • Added support for strings starting with "
  • Added support for array of booleans
  • Added support for float parameters
  • Work for a full normal load of a file, suporting also repeated parameters (array of parameters)
  • VERSION constant added
  • XConfig.Get function implemented for basic parameters (without + or :)

V0.0.1 - 2018-11-14

  • First commit, only work to load basic parameters

Documentation

Overview

Package xconfig loads a configuration file similar to a .ini file, but with some important improvements:

- The xconfig recognize bool, int, float and Strings, and also collections of values and hierarchical nested sub-config sets.

- The xconfig is compatible with XDataset to inject and use in templates, database records, etc.

- You can load more than one file in merge mode or replacing mode in the same config object.

- You can set and get parameters at any time.

- You can load the config object based on a file, but also on a string and another object; this way you can serialize, unserialize, transfer by any strem, save or load on database the object, etc.

- You can also save back the config string with all its comments.

Basic use

1. Installing the package:

Execute on your operating system:

go get -u github.com/webagility-go/xconfig

2. Importing the package:

import "github.com/webability-go/xconfig"

3. Then you need first to create a blank XConfig instance:

xc := xonfig.New()

4. Then, you generally load a file to fill in your XConfig definition

xc.LoadFile("/path/to/my/file.conf")

5. And finally use the configuration

myparam := xc.Get("myparam")

myparam will take the type of the parameter: string, integer, float64, bool, or an array of string, integer or float64 (you should be aware of the type of your parameter before using it)

File format reference

The config file is a simple utf8 flat text file. The configuration file is a set of key=value parameters, with optional comments.

The configuration file have the following syntax:

# this file is named example.conf, used in following examples
# the # denotes a comment.
; is also a comment
parameter1=value1
parameter2=value2
# Repeating the same parameter will create an array of values for this parameter
parameter2=value3

# Creates a sub XConfig dataset for parameter, then again for subparameter
parameter.subparameter.subparameter2=value

# Force to add the value to the parameter (with an extra '+'), in this case to the array of string values of parameter2
parameter2+=value4

# Replace any value the parameter already has by this one (with an extra ':'), in this case parameter2 is a string again
parameter2:=value4

You can add as many as parameters you wish into the file.

1. comments:

You may add comments and also comment unused parameter with # or ; at the beginning of the line

# This is the config file for my application
MAINPATH=/home/var

# Unused parameter:
# DOMAIN=mydomain.com

2. Parameter keys:

The parameter key is a string with characters [a-zA-Z0-9_-] only, with a minimum of 1 character.

The point (.) denotes a sub set of parameters (a new sub XConfig dataset for this parameter)

database.user=username
database.pass=password
database.db=dbname

In this case the database entry of the XConfig is again another XConfig with 3 parameters into it: user, pass and db.

3. Assignation sign:

A simple = sign is the normal assignation, the "add" or "replace" behaviour depends on the funcion called for loading the configuration (Load* or Merge* functions).

In this case various asignation to the same parameter will create an array of values of the same type as the first declared parameter.

An equal sign preceded by a + (+=) will always add the parameter to the array of values, never replace it (see Merge/Load).

An equal sign preceded by a : (:=) will always replace the parameter and discard any already set values.

4. Parameter values:

There are 4 types of values:

- Strings

- Integer

- Float

- Boolean

The value has no restrictions except it must enter into the line (no line breaks allowed) The compiler accepts strings "true", "on", "yes" as a boolean 'true' and "false", "off", "no", "none" as a boolean 'false'. For instance, that means parameter=off is a boolean false, and parameter=yes is a boolean true in the XConfig structure.

The compiler also convert all integers to an int parameter in the XConfig structure, and float values as float64 type. If you want a natural integer, float or boolean interpreted as a string, you must start it with a " character: param1="123 will be the string 123 in the XConfig structure

If you want a string starting with a ", you will need to put 2 " at the beginning: param=""abc will be the string "abc in the XConfig structure

3. list of values:

You can repeat as many time you need the same parameter name with different values. This will build a list of values in the object. The list of values is kept as an array of values.

If you have a mixed type of values, you will get an error

for instance:

# Those are booleans
parameter1=true
parameter2=on
parameter3=no

# Those are integers
parameter4=0
parameter5=1
parameter6=234
parameter7=-5
parameter8=837456783456

# Those are floats
parameter10=0.0
parameter11=1.7
parameter12=234.5
parameter13=-5.834
parameter14=837456783.456
parameter15=-5.834e7

# Those are strings
parameter20=asdh
parameter21="1
parameter22="false
parameter23="-5.834
parameter24=""12345
parameter25=something 123 true false on off

# This parameter will force parameter1 to become an array of booleans [true, false]
parameter1=false

# This will throw an error since parameter1 is a boolean and abc is not a boolean
parameter1=abc

# Note that is the first parameter is a string, all new values will should start with " to be considered as a string also:
parameter30=hello
parameter30="true
parameter30="123
# you will obtain an array []string with values ["hello", "true", "123"]

# List of authorized languages:
languages=es
languages=en
languages=fr
languages=jp

The order IS important.

Once loaded you will get a []string{“es”, “en”, “fr”, “jp”} assigned to the “languages” parameter.

Merging vs Loading

+ and :

You may load two config file (or more), for example when you have a master config file and a local replacement values config file. In this case, the values of the second file will "replace" the data already loaded with the first file. This is a replacement of config entries.

In the other hand, you may merge two config files (or more), for example when you need to fragment the data into a set of simpler files. In this case, the values will just be "added" as if the two files were a simple file (create arrays on same id entries). This is a merging of config entries.

If you want to force the behaviour of variables (merging into a replacement loading, or replace into a merging loading), you may use the two assignement operators + and :

:= will be used to replace a value by a new value, meanwhile += will be used to add a new value to the array of data. The rules of "same type of data" must be observed also in this case (+=)

import "github.com/webability-go/xconfig"

xc := xconfig.New()
xc.LoadFile("/path/to/my/file.conf")
xm := xconfig.New()
xm.LoadFile("/path/to/my/file2.conf")
// merge it:
xc.Merge(xm)

With the following files:

#file.conf: global config:
ip=127.0.0.1
port=80
domain=test.com

#file2.conf: local config:
port=8080
title=Welcome

The result config after merging local into global will be:

ip=127.0.0.1
port=8080
domain=test.com
title=Welcome

Advanced use

The XConfig object is easily usable as:

// Using the New function
config := xconfig.New(nil)

// Auto-new operator
config := &xconfig.XConfig{}

// Default new operator
config := new(xconfig.XConfig)

or, if you load your own file by other means (remote, database etc)

config := &xconfig.XConfig{}
mydata := getMyParameters()   // get the whole configuration file into mydata string
config.LoadString(mydata)

or, if you already have your configuration into a Map of Strings (unserialized, etc)

config := &xconfig.XConfig{}
mydata := map[string]string{"param1":"value1","param2":"value2"}
config.LoadXConfig(mydata)

There are 3 sets of public functions:

Load*: to load a file, a string dataset, or another XConfig dataset. Loading means all already existing parameters will be replaced by the new configuration.

This is useful when you have a main config file, and a local config file that must replace some values Functions are LoadFile, LoadString and LoadXConfig

Merge*: to merge a file, a string dataset, or another XConfig dataset. Merging means all new entries will be added to the already existing parameters.

This is userfull then you split your config file into subset of parameters each (for instance database config, memory config, internationalization config, etc) Functions are MergeFile, MergeString and MergeXConfig

Get/Set/Add: to read, set (replace) or add (merge) parameters to the XConfig.

Once you have an instance of your configuration, you may use it like this:

// assign a local variable
param1 := config.Get("parameter1")
fmt.Println(param1)

// assign to an already casted local variable
var param2 string
param2 = config.Get("parameter2").(string)  // be careful that the parameter IS actually the same cast or an error is thrown
fmt.Println(param2)
// Or, since XConfig is XDataset extended, you may use the autocast functions:
param2 = config.GetString("parameter2")  // Will be converted to a string always

// use directly the parameters
for p, v := range config {
  fmt.Printf("%s=%v\n", p, v)
}

// set a new parameter
config.Set("parameter3", "value3")
config.Set("parameter3", "new value3") // will be replaced
config.Add("parameter3", "another value3") // will be replaced by an array of values with both entries into it
config.Set("parameter4", 12345)
config.Set("parameter5", true)

Advanced topics

Parsing and algorithms

LoadFile: load file in string then call LoadString MergeFile: load file in string then call MergeString loadstring: parse string in temporary XConfig then call LoadXConfig Mergestring: parse string in temporary XConfig then call MergeXConfig LoadXConfig: call parsemap with merge=false MergeConfig: call parsemap with merge=true parsemap:

Index

Constants

View Source
const VERSION = "0.4.0"

VERSION is the used version nombre of the XCore library.

Variables

This section is empty.

Functions

This section is empty.

Types

type Parameter

type Parameter struct {

	// Value of the parameter ()
	Value interface{}
	// contains filtered or unexported fields
}

Parameter is the basic entry parameter into the configuration object Value is the value of the parameter.

func (*Parameter) Clone

func (p *Parameter) Clone() *Parameter

Clone is the parameter method to call to make a full clone of the information

type XConfig

type XConfig struct {
	Parameters map[string]Parameter
	Comments   map[string]string
	Order      []string
	Multiple   bool
	// contains filtered or unexported fields
}

XConfig is the main config object

func New

func New() *XConfig

New is called to create a new empty XConfig object

func (*XConfig) Add

func (c *XConfig) Add(key string, value interface{}) error

Add will adds a value to the structure. If the key entry already exists, then try to build a collection of it

func (*XConfig) Clone

func (c *XConfig) Clone() xcore.XDatasetDef

Clone will perform a full clone of the whole structure

func (*XConfig) Del

func (c *XConfig) Del(key string)

Del will delete then entry key it exists

func (*XConfig) Get

func (c *XConfig) Get(key string) (interface{}, bool)

Get will return the value of the key entry return false as second parameter if the entry does not exists (remember a value can be NIL and exists)

func (*XConfig) GetBool

func (c *XConfig) GetBool(key string) (bool, bool)

GetBool will return the key entry data as a boolean, or false return false as second parameter if the entry does not exists (remember a value can be false and exists)

func (*XConfig) GetBoolCollection

func (c *XConfig) GetBoolCollection(key string) ([]bool, bool)

GetBoolCollection will return the key entry data as a []bool, or nil return false as second parameter if the entry does not exists (remember a value can be nil and exists)

func (*XConfig) GetCollection

func (c *XConfig) GetCollection(key string) (xcore.XDatasetCollectionDef, bool)

GetCollection will return the key entry data as an XDatasetCollectionDef if it exists and is a XDatasetCollectionDef return false as second parameter if the entry does not exists (remember a value can be NIL and exists)

func (*XConfig) GetConfig

func (c *XConfig) GetConfig(key string) *XConfig

GetConfig will return the key entry data as a XConfig, or nil This is similar to the GetDataset function

func (*XConfig) GetDataset

func (c *XConfig) GetDataset(key string) (xcore.XDatasetDef, bool)

GetDataset will return the key entry data as an XDataset if it exists and is a XDatasetDef return false as second parameter if the entry does not exists (remember a value can be NIL and exists)

func (*XConfig) GetFloat

func (c *XConfig) GetFloat(key string) (float64, bool)

GetFloat will return the key entry data as a float64, or 0 return false as second parameter if the entry does not exists (remember a value can be 0 and exists)

func (*XConfig) GetFloatCollection

func (c *XConfig) GetFloatCollection(key string) ([]float64, bool)

GetFloatCollection will return the key entry data as a []float64, or nil return false as second parameter if the entry does not exists (remember a value can be nil and exists)

func (*XConfig) GetInt

func (c *XConfig) GetInt(key string) (int, bool)

GetInt will return the key entry data as an int, or 0 return false as second parameter if the entry does not exists (remember a value can be 0 and exists)

func (*XConfig) GetIntCollection

func (c *XConfig) GetIntCollection(key string) ([]int, bool)

GetIntCollection will return the key entry data as a []int, or nil return false as second parameter if the entry does not exists (remember a value can be nil and exists)

func (*XConfig) GetString

func (c *XConfig) GetString(key string) (string, bool)

GetString will return the key entry data as a string, or "" return false as second parameter if the entry does not exists (remember a value can be "" and exists)

func (*XConfig) GetStringCollection

func (c *XConfig) GetStringCollection(key string) ([]string, bool)

GetStringCollection will return the key entry data as a []string, or nil return false as second parameter if the entry does not exists (remember a value can be nil and exists)

func (*XConfig) GetTime

func (c *XConfig) GetTime(key string) (time.Time, bool)

GetTime will return the key entry data as a time, or 0 return false as second parameter if the entry does not exists (remember a value can be 0 and exists)

func (*XConfig) GetTimeCollection

func (c *XConfig) GetTimeCollection(key string) ([]time.Time, bool)

GetTimeCollection will return the key entry data as a []Time, or nil return false as second parameter if the entry does not exists (remember a value can be nil and exists)

func (*XConfig) GoString

func (c *XConfig) GoString() string

GoString will create a string of the ordered content of the XConfig (based on String)

func (*XConfig) LoadFile

func (c *XConfig) LoadFile(filename string) error

LoadFile will try to load the file and parse it into the XConfig structure

func (*XConfig) LoadString

func (c *XConfig) LoadString(data string) error

LoadString will parse the string into the XConfig structure

func (*XConfig) LoadXConfig

func (c *XConfig) LoadXConfig(data *XConfig) error

LoadXConfig will load the new XConfig into the existing one

func (*XConfig) MergeFile

func (c *XConfig) MergeFile(filename string) error

MergeFile will try to load the file and parse it into the XConfig structure, merging the entries to the existing ones

func (*XConfig) MergeString

func (c *XConfig) MergeString(data string) error

MergeString will parse the string into the XConfig structure, merging the entries to the existing ones

func (*XConfig) MergeXConfig

func (c *XConfig) MergeXConfig(data *XConfig) error

MergeXConfig will merge the new XConfig to the existing one

func (*XConfig) Set

func (c *XConfig) Set(key string, value interface{})

Set will replace or create the value of the key entry

func (*XConfig) String

func (c *XConfig) String() string

String will create a string of the ordered content of the XConfig

type XConfigDef

type XConfigDef interface {
	xcore.XDatasetDef
}

XConfigDef is the config definition type

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL