Skip to content

Commit b8c31ec

Browse files
authored
Add comments and unittests to go-sqlcommenter-core (#218)
1 parent 0579a4a commit b8c31ec

File tree

2 files changed

+127
-9
lines changed

2 files changed

+127
-9
lines changed

go/core/core.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,23 @@ import (
2222
"runtime"
2323
"sort"
2424
"strings"
25-
26-
"go.opentelemetry.io/otel/propagation"
2725
)
2826

27+
// Constants used as key string for tags.
28+
// It is not necessary that all SQLCommenter frameworks/ORMs will contain all these keys i.e.
29+
// it is on best-effort basis.
2930
const (
3031
Route string = "route"
31-
Controller string = "controller"
32-
Action string = "action"
33-
Framework string = "framework"
34-
Driver string = "db_driver"
35-
Traceparent string = "traceparent"
36-
Application string = "application"
32+
Controller = "controller"
33+
Action = "action"
34+
Framework = "framework"
35+
Driver = "db_driver"
36+
Traceparent = "traceparent"
37+
Application = "application"
3738
)
3839

40+
// CommenterConfig contains configurations for SQLCommenter library.
41+
// We can enable and disable certain tags by enabling these configurations.
3942
type CommenterConfig struct {
4043
EnableDBDriver bool
4144
EnableRoute bool
@@ -46,11 +49,15 @@ type CommenterConfig struct {
4649
EnableApplication bool
4750
}
4851

52+
// StaticTags are few tags that can be set by the application and will be constant
53+
// for every API call.
4954
type StaticTags struct {
5055
Application string
5156
DriverName string
5257
}
5358

59+
// CommenterOptions contains all options regarding SQLCommenter library.
60+
// This includes the configurations as well as any static tags.
5461
type CommenterOptions struct {
5562
Config CommenterConfig
5663
Tags StaticTags
@@ -60,13 +67,19 @@ func encodeURL(k string) string {
6067
return url.QueryEscape(k)
6168
}
6269

63-
func GetFunctionName(i interface{}) string {
70+
// GetFunctionName returns the name of the function passed.
71+
func GetFunctionName(i any) string {
6472
if i == nil {
6573
return ""
6674
}
6775
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
6876
}
6977

78+
// ConvertMapToComment returns a comment string given a map of key-value pairs of tags.
79+
// There are few steps involved here:
80+
// - Sorting the tags by key string
81+
// - url encoding the key value pairs
82+
// - Formatting the key value pairs as "key1=value1,key2=value2" format.
7083
func ConvertMapToComment(tags map[string]string) string {
7184
var sb strings.Builder
7285
i, sz := 0, len(tags)
@@ -89,6 +102,7 @@ func ConvertMapToComment(tags map[string]string) string {
89102
return sb.String()
90103
}
91104

105+
// ExtractTraceparent extracts the traceparent field using OpenTelemetry library.
92106
func ExtractTraceparent(ctx context.Context) propagation.MapCarrier {
93107
// Serialize the context into carrier
94108
textMapPropogator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
@@ -97,12 +111,15 @@ func ExtractTraceparent(ctx context.Context) propagation.MapCarrier {
97111
return carrier
98112
}
99113

114+
// RequestTagsProvider adds a basic interface for other libraries like gorilla/mux to implement.
100115
type RequestTagsProvider interface {
101116
Route() string
102117
Action() string
103118
Framework() string
104119
}
105120

121+
// ContextInject injects the tags key-value pairs into context,
122+
// which can be later passed into drivers/ORMs to finally inject them into SQL queries.
106123
func ContextInject(ctx context.Context, h RequestTagsProvider) context.Context {
107124
ctx = context.WithValue(ctx, Route, h.Route())
108125
ctx = context.WithValue(ctx, Action, h.Action())

go/core/core_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package core
2+
3+
import (
4+
"context"
5+
"testing"
6+
)
7+
8+
func TestConvertMapToComment(t *testing.T) {
9+
for _, tc := range []struct {
10+
desc string
11+
tagMap map[string]string
12+
want string
13+
}{
14+
{
15+
desc: "nil tagMap",
16+
want: "",
17+
},
18+
{
19+
desc: "no tags",
20+
tagMap: map[string]string{},
21+
want: "",
22+
},
23+
{
24+
desc: "only one tag",
25+
tagMap: map[string]string{
26+
Route: "test-route",
27+
},
28+
want: "route='test-route'",
29+
},
30+
{
31+
desc: "only one tag with url encoding",
32+
tagMap: map[string]string{
33+
Route: "test/route",
34+
},
35+
want: "route='test%2Froute'",
36+
},
37+
{
38+
desc: "multiple tags",
39+
tagMap: map[string]string{
40+
Route: "test/route",
41+
Action: "test-action",
42+
Driver: "sql-pg",
43+
},
44+
want: "action='test-action',db_driver='sql-pg',route='test%2Froute'",
45+
},
46+
} {
47+
t.Run(tc.desc, func(t *testing.T) {
48+
if got, want := ConvertMapToComment(tc.tagMap), tc.want; got != want {
49+
t.Errorf("ConvertMapToComment(%+v) = %q, want = %q", tc.tagMap, got, want)
50+
}
51+
})
52+
}
53+
}
54+
55+
type testRequestProvider struct {
56+
withRoute string
57+
withAction string
58+
withFramework string
59+
}
60+
61+
func (p *testRequestProvider) Route() string { return p.withRoute }
62+
func (p *testRequestProvider) Action() string { return p.withAction }
63+
func (p *testRequestProvider) Framework() string { return p.withFramework }
64+
65+
func TestContextInject(t *testing.T) {
66+
tagsProvider := &testRequestProvider{
67+
withRoute: "test-route",
68+
withAction: "test-action",
69+
withFramework: "test-framework",
70+
}
71+
ctx := context.Background()
72+
gotCtx := ContextInject(ctx, tagsProvider)
73+
74+
for _, tc := range []struct {
75+
desc string
76+
key string
77+
want string
78+
}{
79+
{
80+
desc: "fetch action",
81+
key: Action,
82+
want: "test-action",
83+
},
84+
{
85+
desc: "fetch route",
86+
key: Route,
87+
want: "test-route",
88+
},
89+
{
90+
desc: "fetch framework",
91+
key: Framework,
92+
want: "test-framework",
93+
},
94+
} {
95+
t.Run(tc.desc, func(t *testing.T) {
96+
if got, want := gotCtx.Value(tc.key), tc.want; got != want {
97+
t.Errorf("ContextInject(ctx, tagsProvider) context.Value(%q) = %q, want = %q", tc.key, got, tc.want)
98+
}
99+
})
100+
}
101+
}

0 commit comments

Comments
 (0)