Documentation ¶
Overview ¶
The package dsn is a toolbox of functions to fill and format structs from varying sources. It acts entirely upon struct metadata.
Index ¶
- func FlagSet(name string, errorHandling flag.ErrorHandling, info interface{}) (*flag.FlagSet, error)
- func FormatSimple(input interface{}) string
- func FormatURI(input interface{}) (string, error)
- func FromEnv(prefix string, input interface{}) error
- func Parse(dsn string, target interface{}) error
- func ParseSimple(dsn string, target interface{}) error
- func ParseURI(dsn string, target interface{}) error
- func TagToField(input interface{}, tagType TagType) map[string]reflect.Value
- type Info
- type TagType
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FlagSet ¶
func FlagSet(name string, errorHandling flag.ErrorHandling, info interface{}) (*flag.FlagSet, error)
FlagSet creates a flag.FlagSet to be used with the stdlib flag package or flag-compatible third party packages.
Flags will be created for members based on their json metadata. If no json metadata is present no flag will be created. If the member has a doc metadata tag its value will be used as the usage argument for the flag.
The resulting FlagSet can be used with e.g. github.com/spf13/pflag to merge multiple FlagSets.
func FormatSimple ¶
func FormatSimple(input interface{}) string
FormatSimple formats the passed value as a simple DSN.
Only members with a json metadata tag are added with the json metadata value used as the key.
Example:
type Example struct { StringA string `json:"a"` IntB int `json:"b"` } ex := new(Example) ex.StringA = "a string" ex.IntB = 5 fmt.Println(dsn.FormatSimple(ex))
Will print:
a="a string" b=5
func FormatURI ¶
FormatURI formats the passed values as a simple URI.
Only members with a json metadata tag are added with the json metadata value used as key. This key should reflect an URI-resource name, e.g. scheme, user, password, host, port. The associated values of these keys are passed to an URL-struct.
Additionally, the keys referring to a userstorekey or database will be added as connection property using their respective key, e.g. "KEY=<userstorekey>" or "database=<database>".
Any key that does not match such URI-resource name will be added as connection property following the scheme: "<key>=<value>". Thus, non-string struct-members that do not match any URI-resource name and default to "0" (int) or "false" (boolean) are added as connection property with their default as value. To avoid possible issues, use string-members with an empty string.
Example:
type Example struct { Scheme string `json:"scheme"` User string `json:"user"` Pass string `json:"pass"` Host string `json:"host"` Port int `json:"port"` Database string `json:"database"` ConnectProp1 bool `json:"connectProp1"` ConnectProp2 string `json:"connectProp2"` } ex := new(Example) ex.Scheme = "db" ex.User = "username" ex.Pass = "password" ex.Host = "hostname" ex.Port = 12345 ex.Database = "db1" ex.ConnectProp1 = false ex.ConnectProp2 = "connectionProperty" uri, err := dsn.FormatURI(ex) if err != nil { fmt.Errorf("Something failed: %w", err) } fmt.Println(uri)
Will print:
db://username:password@hostname:12345/?database=db1&connectProp1=false&connectProp2=connectionProperty
For more examples see format_test.go
func FromEnv ¶
FromEnv reads values from environment variables into the given input.
Environment variables are matched to members of the input based on the json and multiref metadata tags.
Example:
os.Setenv("MY_MEMBER", "an example") os.Setenv("MY_SECOND_MEMBER", "5") type Example struct { Member string `json:"member"` AnotherMember int `json:"another-member" multiref:"second-member"` } ex := new(Example) if err := FromEnv("MY", ex); err != nil { return err }
ex.Member will be "an example" and ex.AnotherMember will be 5.
Also see dsn/examples/from_env.
func Parse ¶
Parse uses ParseURI or ParseSimple and returns the respective error. The decision is made based on the existence of "://" in the passed string.
func ParseSimple ¶
ParseSimple parses a simple DSN in the form of "key=value k2=v2".
Only members with a json or multiref metadata tag will be filled. Should be member have both json and multiref tags which occur multiple times in the passed string the last occurrence will take priority.
ParseSimple supports whitespaces in values, but not in keys - given that values are quoted with either double or single quotes.
Example:
type Example struct { // Recognized as "hostname", "host" and "remote" Host string `json:"hostname" multiref:"host,remote"` // Only recognized as "port" Port string `json:"port"` // Recognized as "database" and "db" Database string `json:"database" multiref:"db"` // Not recognized due to missing metadata Username string } ex := new(Example) simple := `host="a.b.c.d" remote='w.x.y.z' port=ssl username="user"` if err := dsn.ParseSimple(simple, ex); err != nil { return err }
Will result in :
ex.Host being set to "w.x.y.z" as it's multiref tag 'remote' came last. ex.Port being set to "ssl". ex.Database not being set as no values were provided. ex.Username not being set as it has no metadata.
func ParseURI ¶
ParseURI uses url.Parse to parse the passed string.
Only members with json metadata tags will be filled. Additionally multiref metadata tags are recognized.
Hostname, Port, Username and Password are hardcoded to be set to "hostname", "port", "username" and "password" respectively due to technical limitations.
If the "database" tag is set its member is set to the path of the URI, sans the leading "/".
func TagToField ¶
TagToField returns a mapping from json metadata tags to reflect.Values.
If TagType OnlyJSON is passed only the json tag will be mapped. If the TagType MultiRef is passed the tags from the `multiref` metadata tag will also be mapped to their field.Value.
Example:
type Example struct { Host `json:"host" multiref:"hostname"` } example := Example{Host: "host.name.tld"} TagToField(example, OnlyJSON) -> map[string]reflect.Value{ "host": example.Host, } TagToField(example, Multiref) -> map[string]reflect.Value{ "host": example.Host, "hostname": example.Host, }
If the TagType Doc is passed the json metadata tag value will be mapped to a reflect.Value of Kind string containing the value of the doc metadata tag..
Example:
type Example struct { Host `json:"hostname" doc:"Hostname to connect to"` } example := new(Example) TagToField(example, Doc) -> map[string]reflect.Value{ "hostname": reflect.ValueOf("Hostname to connect to"), }
If the input is a pointer the reflect.Values will be addressable and settable - allowing to modify the fields of the passed structure.
Example:
type Example struct { Host `json:"host"` } example := Example{Host: "old.host.name"} ttf := TagToField(&example, OnlyJSON) ttf["host"].SetString("new.host.name") fmt.Println(example.Host) -> "new.host.name"
Types ¶
type Info ¶
type Info struct { Host string `json:"host" multiref:"hostname" doc:"Hostname to connect to"` Port string `json:"port" doc:"Port (Example: '443' or 'tls') to connect to"` Username string `json:"username" multiref:"user" doc:"Username"` Password string `json:"password" multiref:"passwd,pass" doc:"Password"` Database string `json:"database" multiref:"db" doc:"Database"` }
Info serves as both an example and an embeddable default to use in DSN structs.