From 4d0e58a911e6d44e2135ef75a0ad6dbfc117a00b Mon Sep 17 00:00:00 2001 From: Mike Mikhailov Date: Sun, 25 Apr 2021 16:09:29 +0300 Subject: [PATCH 1/2] data-unmarshal: upd deps --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index e5f8fed..d7ddfcb 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/wtask-go/mixpanel go 1.16 require ( - github.com/getkin/kin-openapi v0.53.0 + github.com/getkin/kin-openapi v0.60.0 github.com/golangci/golangci-lint v1.39.0 - github.com/psampaz/go-mod-outdated v0.7.0 + github.com/psampaz/go-mod-outdated v0.8.0 github.com/santhosh-tekuri/jsonschema/v3 v3.0.1 ) From 7434396d53f203c2f51eb6192b195841c3b953ff Mon Sep 17 00:00:00 2001 From: Mike Mikhailov Date: Mon, 26 Apr 2021 01:14:07 +0300 Subject: [PATCH 2/2] data-unmarshal: Unmarshaler --- .golangci.yml | 5 ++- ingestion/event/event.go | 67 ++++++++++++++++++++++++++++++++++++ ingestion/event/json_test.go | 43 +++++++++++++++++++++++ 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 ingestion/event/json_test.go diff --git a/.golangci.yml b/.golangci.yml index a73150e..d295b76 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -68,7 +68,7 @@ linters-settings: statements: 40 gocognit: - min-complexity: 20 + min-complexity: 25 goconst: min-len: 3 @@ -116,7 +116,7 @@ linters-settings: skipRecvDeref: true gocyclo: - min-complexity: 20 + min-complexity: 25 gofmt: simplify: true @@ -240,7 +240,6 @@ linters: - gocognit - goconst - gocritic - - goerr113 - gofmt - golint - goprintffuncname diff --git a/ingestion/event/event.go b/ingestion/event/event.go index ed94269..15789e5 100644 --- a/ingestion/event/event.go +++ b/ingestion/event/event.go @@ -109,3 +109,70 @@ func (p *Properties) MarshalJSON() ([]byte, error) { return json.Marshal(obj) } + +// UnmarshalJSON implements json.Unmarshaler interface. +// nolint:funlen // it is required parse raw data +func (p *Properties) UnmarshalJSON(raw []byte) error { + if p == nil { + return fmt.Errorf("unmarshal event.Properties to nil") + } + + data := map[string]json.RawMessage{} + if err := json.Unmarshal(raw, &data); err != nil { + return err + } + + unmarshal := func(key string, target interface{}) error { + if v, ok := data[key]; ok { + if err := json.Unmarshal(v, target); err != nil { + return err + } + + delete(data, key) + } + + return nil + } + + if err := unmarshal("$insert_id", &p.InsertID); err != nil { + return err + } + + if err := unmarshal("distinct_id", &p.DistinctID); err != nil { + return err + } + + if err := unmarshal("ip", &p.IP); err != nil { + return err + } + + var unix int64 + if err := unmarshal("time", &unix); err != nil { + return err + } + + if unix != 0 { + p.Time = time.Unix(unix, 0).UTC() + } + + if err := unmarshal("token", &p.Token); err != nil { + return err + } + + if len(data) > 0 { + if p.CustomProperties == nil { + p.CustomProperties = CustomProperties{} + } + + for k, v := range data { + var c interface{} + if err := json.Unmarshal(v, &c); err != nil { + return err + } + + p.CustomProperties[k] = c + } + } + + return nil +} diff --git a/ingestion/event/json_test.go b/ingestion/event/json_test.go new file mode 100644 index 0000000..10e293d --- /dev/null +++ b/ingestion/event/json_test.go @@ -0,0 +1,43 @@ +package event_test + +import ( + "encoding/json" + "reflect" + "testing" + "time" + + "github.com/wtask-go/mixpanel/ingestion/event" +) + +func TestData_json(t *testing.T) { + now := time.Now().Truncate(1 * time.Second).UTC() + src := event.Data{ + Event: "test", + Properties: event.Properties{ + InsertID: "test-insert-id", + DistinctID: "test-distinct-id", + IP: "ip-address", + Time: now, + Token: "test-token", + CustomProperties: event.CustomProperties{ + "string": "test-custom-string", + "logical": true, + "number": 3.14, + }, + }, + } + + srcJSON, err := json.Marshal(&src) + if err != nil { + t.Fatal(err) + } + + data := event.Data{} + if err = json.Unmarshal(srcJSON, &data); err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(data, src) { + t.Fatalf("source: %+v, actual: %+v", src, data) + } +}