Skip to content

Commit 21f2303

Browse files
authored
fix datasourceRef marshalling when embedded (#981)
1 parent 928932d commit 21f2303

File tree

2 files changed

+61
-13
lines changed

2 files changed

+61
-13
lines changed

experimental/apis/data/v0alpha1/query.go

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
func init() { //nolint:gochecknoinits
1717
jsoniter.RegisterTypeEncoder("v0alpha1.DataQuery", &genericQueryCodec{})
1818
jsoniter.RegisterTypeDecoder("v0alpha1.DataQuery", &genericQueryCodec{})
19+
jsoniter.RegisterTypeDecoder("v0alpha1.DataSourceRef", &datasourceRefCodec{})
1920
}
2021

2122
type QueryDataRequest struct {
@@ -157,6 +158,7 @@ func (g *DataQuery) GetString(key string) string {
157158
}
158159

159160
type genericQueryCodec struct{}
161+
type datasourceRefCodec struct{}
160162

161163
func (codec *genericQueryCodec) IsEmpty(_ unsafe.Pointer) bool {
162164
return false
@@ -180,6 +182,33 @@ func (codec *genericQueryCodec) Decode(ptr unsafe.Pointer, iter *j.Iterator) {
180182
*((*DataQuery)(ptr)) = q
181183
}
182184

185+
// Long ago dashboards referenced data sources with only the name
186+
func (codec *datasourceRefCodec) Decode(ptr unsafe.Pointer, iter *j.Iterator) {
187+
q := DataSourceRef{}
188+
switch iter.WhatIsNext() {
189+
case j.StringValue:
190+
q.UID = iter.ReadString()
191+
case j.ObjectValue:
192+
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
193+
if iter.Error != nil {
194+
return
195+
}
196+
switch field {
197+
case "type":
198+
q.Type = iter.ReadString()
199+
case "uid":
200+
q.UID = iter.ReadString()
201+
default:
202+
_ = iter.Read() // ignore unused properties
203+
}
204+
}
205+
default:
206+
iter.Error = fmt.Errorf("expected string or object")
207+
return
208+
}
209+
*((*DataSourceRef)(ptr)) = q
210+
}
211+
183212
// MarshalJSON writes JSON including the common and custom values
184213
func (g DataQuery) MarshalJSON() ([]byte, error) {
185214
cfg := j.ConfigCompatibleWithStandardLibrary
@@ -199,6 +228,15 @@ func (g *DataQuery) UnmarshalJSON(b []byte) error {
199228
return g.readQuery(iter)
200229
}
201230

231+
// UnmarshalJSON reads a query from json byte array
232+
func (g *DataSourceRef) UnmarshalJSON(b []byte) error {
233+
iter, err := jsoniter.ParseBytes(jsoniter.ConfigDefault, b)
234+
if err != nil {
235+
return err
236+
}
237+
return iter.Unmarshal(b, g)
238+
}
239+
202240
func (g *DataQuery) DeepCopyInto(out *DataQuery) {
203241
*out = *g
204242
g.CommonQueryProperties.DeepCopyInto(&out.CommonQueryProperties)
@@ -305,19 +343,7 @@ func (g *CommonQueryProperties) readQuery(iter *jsoniter.Iterator,
305343
err = iter.ReadVal(&g.TimeRange)
306344
case "datasource":
307345
// Old datasource values may just be a string
308-
next, err = iter.WhatIsNext()
309-
if err != nil {
310-
return err
311-
}
312-
switch next {
313-
case j.StringValue:
314-
g.Datasource = &DataSourceRef{}
315-
g.Datasource.UID, err = iter.ReadString()
316-
case j.ObjectValue:
317-
err = iter.ReadVal(&g.Datasource)
318-
default:
319-
return fmt.Errorf("expected string or object")
320-
}
346+
err = iter.ReadVal(&g.Datasource)
321347

322348
case "datasourceId":
323349
g.DatasourceID, err = iter.ReadInt64()

experimental/apis/data/v0alpha1/query_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,28 @@ func TestParseQueriesIntoQueryDataRequest(t *testing.T) {
9090
})
9191
}
9292

93+
func TestLegacyDataSourceRef(t *testing.T) {
94+
type testWrapper struct {
95+
Ref DataSourceRef `json:"ref"`
96+
}
97+
98+
wrap := &testWrapper{}
99+
err := json.Unmarshal([]byte(`{ "ref": {"type":"ttt", "uid":"UID"}}`), wrap)
100+
require.NoError(t, err)
101+
require.Equal(t, "ttt", wrap.Ref.Type)
102+
require.Equal(t, "UID", wrap.Ref.UID)
103+
104+
err = json.Unmarshal([]byte(`{ "ref": "name"}`), wrap)
105+
require.NoError(t, err)
106+
require.Equal(t, "", wrap.Ref.Type)
107+
require.Equal(t, "name", wrap.Ref.UID)
108+
109+
ref := &DataSourceRef{}
110+
err = json.Unmarshal([]byte(`"aaa"`), ref) // string as reference
111+
require.NoError(t, err)
112+
require.Equal(t, "aaa", ref.UID)
113+
}
114+
93115
func TestQueryBuilders(t *testing.T) {
94116
prop := "testkey"
95117
testQ1 := &DataQuery{}

0 commit comments

Comments
 (0)