Skip to content
This repository was archived by the owner on Apr 17, 2019. It is now read-only.

Commit 5baf9f7

Browse files
author
Murat Kabilov
committed
remove helpers
1 parent f10edd6 commit 5baf9f7

File tree

2 files changed

+207
-212
lines changed

2 files changed

+207
-212
lines changed

pkg/config/config.go

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,34 @@ import (
44
"fmt"
55
"os"
66
"path"
7+
"regexp"
8+
"strconv"
9+
"strings"
710

811
"gopkg.in/yaml.v2"
912
)
1013

14+
// Column usage types
15+
const (
16+
Discard ColumnUsage = iota // Ignore this column
17+
Label // Use this column as a label
18+
Counter // Use this column as a counter
19+
Gauge // Use this column as a gauge
20+
21+
NoVersion PgVersion = -1
22+
)
23+
24+
var (
25+
pgVerRegex = regexp.MustCompile(`^(\d+)(?:\.(\d+))?(?:\.(\d+))?$`)
26+
27+
columnUsageMapping = map[string]ColumnUsage{
28+
"DISCARD": Discard,
29+
"LABEL": Label,
30+
"COUNTER": Counter,
31+
"GAUGE": Gauge,
32+
}
33+
)
34+
1135
// ConfigInterface describes Config methods
1236
type ConfigInterface interface {
1337
Load() error
@@ -21,6 +45,189 @@ type Config struct {
2145
dbs map[string]DbConfig
2246
}
2347

48+
// ColumnUsage describes column usage
49+
type ColumnUsage int
50+
51+
// PgVersion describes version in server_version_num format
52+
type PgVersion int
53+
54+
// Metrics describe metrics
55+
type Metrics map[string]Metric
56+
57+
// VerSQLs contain version specific SQLs
58+
type VerSQLs []VerSQL
59+
60+
// Metric describes metric
61+
type Metric struct {
62+
Usage ColumnUsage `yaml:"usage"`
63+
Description string `yaml:"description"`
64+
}
65+
66+
// VerSQL describes PostgreSQL version specific SQL
67+
type VerSQL struct {
68+
SQL string
69+
MinVer PgVersion
70+
MaxVer PgVersion
71+
}
72+
73+
// Query describes query
74+
type Query struct {
75+
Name string
76+
Metrics Metrics `yaml:"metrics"`
77+
VerSQL VerSQLs `yaml:"query"`
78+
NameColumn string `yaml:"nameColumn"`
79+
ValueColumn string `yaml:"valueColumn"`
80+
}
81+
82+
// UnmarshalYAML unmarshals the yaml
83+
func (v *VerSQLs) UnmarshalYAML(unmarshal func(interface{}) error) error {
84+
res := make(VerSQLs, 0)
85+
var val interface{}
86+
87+
err := unmarshal(&val)
88+
if err != nil {
89+
return fmt.Errorf("could not unmarshal: %v", err)
90+
}
91+
92+
switch val := val.(type) {
93+
case map[interface{}]interface{}:
94+
for k, v := range val {
95+
minPg, maxPg := parseVersionRange(fmt.Sprintf("%v", k))
96+
res = append(res, VerSQL{
97+
MinVer: minPg,
98+
MaxVer: maxPg,
99+
SQL: v.(string),
100+
})
101+
}
102+
case interface{}:
103+
res = append(res, VerSQL{
104+
SQL: val.(string),
105+
})
106+
}
107+
108+
*v = res
109+
110+
return nil
111+
}
112+
113+
// UnmarshalYAML unmarshals the yaml
114+
func (c *ColumnUsage) UnmarshalYAML(unmarshal func(interface{}) error) error {
115+
var value string
116+
unmarshal(&value)
117+
cu, ok := columnUsageMapping[value]
118+
if !ok {
119+
return fmt.Errorf("unknown usage: %v", value)
120+
}
121+
122+
*c = cu
123+
124+
return nil
125+
}
126+
127+
// UnmarshalYAML unmarshals the yaml
128+
func (m *Metrics) UnmarshalYAML(unmarshal func(interface{}) error) error {
129+
value := make(map[string]Metric, 0)
130+
queryMetrics := make([]map[string]Metric, 0)
131+
132+
if err := unmarshal(&queryMetrics); err != nil {
133+
return err
134+
}
135+
136+
for _, metrics := range queryMetrics {
137+
for name, descr := range metrics {
138+
value[name] = descr
139+
}
140+
}
141+
142+
*m = value
143+
144+
return nil
145+
}
146+
147+
// UnmarshalYAML unmarshals the yaml
148+
func (v *PgVersion) UnmarshalYAML(unmarshal func(interface{}) error) error {
149+
var str string
150+
if err := unmarshal(&str); err != nil {
151+
return err
152+
}
153+
154+
val := strings.Replace(str, ".", "", -1)
155+
intVal, err := strconv.Atoi(val)
156+
if err != nil {
157+
return fmt.Errorf("could not convert string: %v", err)
158+
}
159+
*v = PgVersion(intVal)
160+
return nil
161+
}
162+
163+
// PgVersion returns string representation of the version
164+
func (v PgVersion) String() string {
165+
return fmt.Sprintf("%d.%d.%d", v/10000, (v/100)%100, v%100)
166+
}
167+
168+
// Query returns query for the requested postgresql version
169+
func (v VerSQLs) Query(version PgVersion) string {
170+
if version == NoVersion ||
171+
(len(v) == 1 && v[0].MaxVer == PgVersion(0) && v[0].MinVer == PgVersion(0)) {
172+
return v[0].SQL
173+
}
174+
175+
for _, query := range v {
176+
if (version >= query.MinVer || query.MinVer == 0) && (version < query.MaxVer || query.MaxVer == 0) {
177+
return query.SQL
178+
}
179+
}
180+
181+
return ""
182+
}
183+
184+
func parseVersion(str string) PgVersion {
185+
var res int
186+
matches := pgVerRegex.FindStringSubmatch(str)
187+
if matches == nil {
188+
return PgVersion(res)
189+
}
190+
if matches[1] != "" {
191+
val, _ := strconv.Atoi(matches[1])
192+
res = val * 10000
193+
if val > 9 && matches[2] != "" {
194+
val, _ := strconv.Atoi(matches[2])
195+
res += val
196+
} else if matches[2] != "" {
197+
val, _ := strconv.Atoi(matches[2])
198+
res += val * 100
199+
if matches[3] != "" {
200+
val, _ := strconv.Atoi(matches[3])
201+
res += val
202+
}
203+
}
204+
}
205+
206+
return PgVersion(res)
207+
}
208+
209+
func parseVersionRange(str string) (PgVersion, PgVersion) {
210+
var min, max PgVersion
211+
if str == "" {
212+
return min, max
213+
}
214+
215+
parts := strings.Split(str, "-")
216+
if len(parts) == 1 {
217+
min = parseVersion(parts[0])
218+
max = min
219+
} else {
220+
if parts[0] != "" {
221+
min = parseVersion(parts[0])
222+
}
223+
if parts[1] != "" {
224+
max = parseVersion(parts[1])
225+
}
226+
}
227+
228+
return min, max
229+
}
230+
24231
// New creates new config
25232
func New(filename string) *Config {
26233
cfg := Config{

0 commit comments

Comments
 (0)