-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathtags.go
More file actions
59 lines (52 loc) · 1.27 KB
/
tags.go
File metadata and controls
59 lines (52 loc) · 1.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package sqlcomment
import (
"fmt"
"net/url"
"sort"
"strings"
)
const (
KeyDBDriver = "db_driver"
KeyFramework = "framework"
KeyApplication = "application"
KeyRoute = "route"
KeyController = "controller"
KeyAction = "action"
)
// Tags represents key value pairs which can be serialized into SQL comment.
// see https://google.github.io/sqlcommenter/spec/
type Tags map[string]string
func encodeValue(v string) string {
urlEscape := strings.ReplaceAll(url.PathEscape(string(v)), "+", "%20")
return fmt.Sprintf("'%s'", urlEscape)
}
func encodeKey(k string) string {
return url.QueryEscape(string(k))
}
// Marshal returns the sqlcomment encoding of t following the spec (see https://google.github.io/sqlcommenter/).
func (t Tags) Marshal() string {
kv := make([]struct{ k, v string }, 0, len(t))
for k := range t {
kv = append(kv, struct{ k, v string }{encodeKey(k), encodeValue(t[k])})
}
sort.Slice(kv, func(i, j int) bool {
return kv[i].k < kv[j].k
})
var b strings.Builder
for i, p := range kv {
if i > 0 {
b.WriteByte(',')
}
fmt.Fprintf(&b, "%s=%s", p.k, p.v)
}
return b.String()
}
// Merge copies given tags into sc.
func (t Tags) Merge(tags ...Tags) Tags {
for _, c := range tags {
for k, v := range c {
t[k] = v
}
}
return t
}