First commit
This commit is contained in:
commit
490ecb0be2
|
@ -0,0 +1,9 @@
|
|||
module git.bit5.ru/backend/clickhouse
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.6.1
|
||||
git.bit5.ru/backend/errors v1.0.0
|
||||
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,86 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"git.bit5.ru/backend/errors"
|
||||
)
|
||||
|
||||
// username/password - auth credentials
|
||||
// database - select the current default database
|
||||
// read_timeout/write_timeout - timeout in second
|
||||
// no_delay - disable/enable the Nagle Algorithm for tcp socket (default is 'true' - disable)
|
||||
// alt_hosts - comma separated list of single address host for load-balancing
|
||||
// connection_open_strategy - random/in_order (default random).
|
||||
// random - choose random server from set
|
||||
// in_order - first live server is chosen in specified order
|
||||
// block_size - maximum rows in block (default is 1000000). If the rows are larger then the data will be split into several blocks to send them to the server
|
||||
// pool size - maximum amount of preallocated byte chunks used in queries (default is 100). Decrease this if you experience memory problems at the expense of more GC pressure and vice versa.
|
||||
// debug - enable debug output (boolean value)
|
||||
|
||||
// Load
|
||||
func Load(path string) (ClickhouseSettings, error) {
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return ClickhouseSettings{}, errors.WithStack(err)
|
||||
}
|
||||
settings := ClickhouseSettings{}
|
||||
if err := json.Unmarshal(bytes, &settings); err != nil {
|
||||
return ClickhouseSettings{}, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
// ClickhouseSettings
|
||||
type ClickhouseSettings struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Database string `json:"database"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
|
||||
Options map[string]json.RawMessage `json:"opts"`
|
||||
}
|
||||
|
||||
func (s ClickhouseSettings) DSN() string {
|
||||
options := url.Values{
|
||||
"database": []string{s.Database},
|
||||
}
|
||||
if len(s.Username) > 0 {
|
||||
options.Set("username", s.Username)
|
||||
}
|
||||
if len(s.Password) > 0 {
|
||||
options.Set("password", s.Password)
|
||||
}
|
||||
|
||||
for name, value := range s.Options {
|
||||
var valueString string
|
||||
|
||||
if value[0] == '"' {
|
||||
if err := json.Unmarshal(value, &valueString); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
var valueInt int
|
||||
if err := json.Unmarshal(value, &valueInt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
valueString = strconv.Itoa(valueInt)
|
||||
}
|
||||
|
||||
options.Set(name, valueString)
|
||||
}
|
||||
|
||||
uri := url.URL{
|
||||
Scheme: "tcp",
|
||||
Host: fmt.Sprintf("%s:%d", s.Host, s.Port),
|
||||
RawQuery: options.Encode(),
|
||||
}
|
||||
|
||||
return uri.String()
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package settings_test
|
||||
|
||||
import (
|
||||
"clickhouse/settings"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
expectedSettings := settings.ClickhouseSettings{
|
||||
Host: "localhost",
|
||||
Port: 9000,
|
||||
Database: "regency_dev",
|
||||
Options: map[string]json.RawMessage{
|
||||
"read_timeout": json.RawMessage(`1`),
|
||||
"no_delay": json.RawMessage(`"disable"`),
|
||||
},
|
||||
}
|
||||
|
||||
actualSettings, err := settings.Load("./test_settings.json")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, expectedSettings, actualSettings)
|
||||
|
||||
}
|
||||
func TestClickhouseSettings(t *testing.T) {
|
||||
t.Run("DSN", func(t *testing.T) {
|
||||
clickSettings := settings.ClickhouseSettings{
|
||||
Host: "localhost",
|
||||
Port: 9000,
|
||||
Username: "user",
|
||||
Password: "pwd#1",
|
||||
Database: "regency_dev",
|
||||
Options: map[string]json.RawMessage{
|
||||
"read_timeout": json.RawMessage(`1`),
|
||||
"no_delay": json.RawMessage(`"disable"`),
|
||||
},
|
||||
}
|
||||
|
||||
expectedDSN := "tcp://localhost:9000?database=regency_dev&no_delay=disable&password=pwd%231&read_timeout=1&username=user"
|
||||
|
||||
assert.Equal(t, expectedDSN, clickSettings.DSN())
|
||||
})
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"host": "localhost",
|
||||
"port": 9000,
|
||||
"database": "regency_dev",
|
||||
"opts": {
|
||||
"read_timeout": 1,
|
||||
"no_delay": "disable"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue