From 6582ac8221ca7bcda4c73b27c9866a2f6c7c1935 Mon Sep 17 00:00:00 2001 From: liyang Date: Tue, 3 Dec 2024 10:59:21 +0800 Subject: [PATCH] refactor: add more example of writing json data (#55) * refactor: add more example of writing json data * chore: log format * chore: log format --- README.md | 31 +++++----- examples/healthcheck/main.go | 2 +- examples/hints/main.go | 4 +- examples/jsondata/README.md | 39 +++++++----- examples/jsondata/main.go | 110 ++++++++++++++++++++++++++++----- examples/object/main.go | 30 ++++----- examples/opentelemetry/main.go | 6 +- examples/table/main.go | 54 ++++++++-------- 8 files changed, 179 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index ade6701..1505e21 100644 --- a/README.md +++ b/README.md @@ -200,27 +200,28 @@ affected, err := cli.CloseStream(ctx) The **GreptimeDB** column is for the datatypes supported in library, and the **Go** column is the matched Go type. -| GreptimeDB | Go | Description | -|----------------------------------|------------------|----------------------------------------| -| INT8 | int8 | | -| INT16 | int16 | | -| INT32 | int32 | | -| INT64, INT | int64 | | -| UINT8 | uint8 | | -| UINT16 | uint16 | | -| UINT32 | uint32 | | -| UINT64, UINT | uint64 | | -| FLOAT32 | float32 | | -| FLOAT64, FLOAT | float64 | | -| BOOLEAN, BOOL | bool | | -| STRING | string | | -| BINARY, BYTES | []byte | | +| GreptimeDB | Go | Description | +|----------------------------------|--------------------|----------------------------------------| +| INT8 | int8 | | +| INT16 | int16 | | +| INT32 | int32 | | +| INT64, INT | int64 | | +| UINT8 | uint8 | | +| UINT16 | uint16 | | +| UINT32 | uint32 | | +| UINT64, UINT | uint64 | | +| FLOAT32 | float32 | | +| FLOAT64, FLOAT | float64 | | +| BOOLEAN, BOOL | bool | | +| STRING | string | | +| BINARY, BYTES | []byte | | | DATE | *Int* or time.Time | the day elapsed since 1970-1-1 | | DATETIME | *Int* or time.Time | the millisecond elapsed since 1970-1-1 | | TIMESTAMP_SECOND | *Int* or time.Time | | | TIMESTAMP_MILLISECOND, TIMESTAMP | *Int* or time.Time | | | TIMESTAMP_MICROSECOND | *Int* or time.Time | | | TIMESTAMP_NANOSECOND | *Int* or time.Time | | +| JSON | string | | NOTE: *Int* is for all of Integer and Unsigned Integer in Go diff --git a/examples/healthcheck/main.go b/examples/healthcheck/main.go index f10dd50..a3d6a5b 100644 --- a/examples/healthcheck/main.go +++ b/examples/healthcheck/main.go @@ -50,7 +50,7 @@ func newClient() (*client, error) { func main() { c, err := newClient() if err != nil { - log.Fatalf("failed to new client: %v:", err) + log.Fatalf("failed to new client: %v", err) } _, err = c.client.HealthCheck(context.Background()) diff --git a/examples/hints/main.go b/examples/hints/main.go index 772e924..933ccf3 100644 --- a/examples/hints/main.go +++ b/examples/hints/main.go @@ -130,10 +130,10 @@ func main() { c, err := newClient() if err != nil { - log.Fatalf("failed to new client: %v:", err) + log.Fatalf("failed to new client: %v", err) } if err = c.write(data); err != nil { - log.Fatalf("failed to write data: %v:", err) + log.Fatalf("failed to write data: %v", err) } } diff --git a/examples/jsondata/README.md b/examples/jsondata/README.md index d1d4101..0b3e26f 100644 --- a/examples/jsondata/README.md +++ b/examples/jsondata/README.md @@ -9,7 +9,9 @@ go run main.go Output: ```log -2024/11/11 14:59:56 affected rows: 1 +2024/11/27 22:26:54 affected rows: 1 +2024/11/27 22:26:54 affected rows: 1 +2024/11/27 22:26:54 affected rows: 1 ``` ## Query @@ -19,30 +21,33 @@ Your can using [MySQL Client](https://docs.greptime.com/user-guide/protocols/mys ```shell $ mysql -h 127.0.0.1 -P 4002 -mysql> select * from json_data; -+-----------------------------------------------------------------------------------------+----------------------------+ -| my_json | timestamp | -+-----------------------------------------------------------------------------------------+----------------------------+ -| {"Age":25,"Courses":["math","history","chemistry"],"IsStudent":false,"Name":"Jain Doe"} | 2024-11-11 06:59:56.340132 | -+-----------------------------------------------------------------------------------------+----------------------------+ -1 row in set (0.04 sec) +mysql> select *from json_data; ++------+------------------------------------------------------------------------------------+----------------------------+ +| id | my_json | ts | ++------+------------------------------------------------------------------------------------+----------------------------+ +| 1 | {"Age":25,"Courses":["math","history","chemistry"],"IsStudent":false,"Name":"doe"} | 2024-11-27 14:26:54.772697 | +| 2 | {"city":"New York","description":"Partly cloudy","temperature":22} | 2024-11-27 14:26:54.772698 | +| 3 | {"Age":23,"Courses":["archaeology","physics"],"IsStudent":true,"Name":"Cherry"} | 2024-11-27 14:26:54.772698 | ++------+------------------------------------------------------------------------------------+----------------------------+ +3 rows in set (0.04 sec) ``` You can view table fields using `show create table` command: ```mysql mysql> show create table json_data; -+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------+ -| Table | Create Table | -+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Table | Create Table | ++-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_data | CREATE TABLE IF NOT EXISTS `json_data` ( + `id` BIGINT NULL, `my_json` JSON NULL, - `timestamp` TIMESTAMP(6) NOT NULL, - TIME INDEX (`timestamp`) + `ts` TIMESTAMP(6) NOT NULL, + TIME INDEX (`ts`), + PRIMARY KEY (`id`) ) - ENGINE=mito - | -+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------+ -1 row in set (0.00 sec) +| ++-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +1 row in set (0.02 sec) ``` diff --git a/examples/jsondata/main.go b/examples/jsondata/main.go index 4371291..bbdab30 100644 --- a/examples/jsondata/main.go +++ b/examples/jsondata/main.go @@ -16,6 +16,7 @@ package main import ( "context" + "encoding/json" "log" "time" @@ -32,6 +33,12 @@ const ( database = "public" ) +type Monitor struct { + ID int64 `greptime:"tag;column:id;type:int64"` + JsonData string `greptime:"column:my_json;type:json"` + Ts time.Time `greptime:"timestamp;column:ts;type:timestamp;precision:microsecond"` +} + type Person struct { Name string Age int @@ -61,45 +68,84 @@ func newClient() (*client, error) { func main() { c, err := newClient() if err != nil { - log.Fatalf("failed to new client: %v:", err) + log.Fatalf("failed to new client: %v", err) } - data, err := initData() + tb, obj1, obj2, err := initData() if err != nil { - log.Fatalf("failed to init data: %v:", err) + log.Fatalf("failed to init data: %v", err) + } + + if err = c.write(tb); err != nil { + log.Fatalf("failed to write data: %v", err) + } + if err = c.writeObject(obj1); err != nil { + log.Fatalf("failed to write object data: %v", err) } - if err = c.write(data); err != nil { - log.Fatalf("failed to write data: %v:", err) + if err = c.streamWriteObject(obj2); err != nil { + log.Fatalf("failed to stream write object data: %v", err) } } -func initData() (*table.Table, error) { +func (Monitor) TableName() string { + return "json_data" +} + +func initData() (*table.Table, *Monitor, *Monitor, error) { time1 := time.Now() + time2 := time.Now() + time3 := time.Now() - itbl, err := table.New("json_data") + tb, err := table.New("json_data") if err != nil { - return nil, err + return nil, nil, nil, err } - p := Person{ - Name: "Jain Doe", + doeProfile := Person{ + Name: "doe", Age: 25, IsStudent: false, Courses: []string{"math", "history", "chemistry"}, } // add column at first. This is to define the schema of the table. - if err := itbl.AddFieldColumn("my_json", types.JSON); err != nil { - return nil, err + if err := tb.AddTagColumn("id", types.INT64); err != nil { + return nil, nil, nil, err } - if err := itbl.AddTimestampColumn("timestamp", types.TIMESTAMP_MICROSECOND); err != nil { - return nil, err + if err := tb.AddFieldColumn("my_json", types.JSON); err != nil { + return nil, nil, nil, err } - if err := itbl.AddRow(p, time1); err != nil { - return nil, err + if err := tb.AddTimestampColumn("ts", types.TIMESTAMP_MICROSECOND); err != nil { + return nil, nil, nil, err + } + if err := tb.AddRow(1, doeProfile, time1); err != nil { + return nil, nil, nil, err + } + + weatherInfo := `{"city":"New York","temperature":22,"description":"Partly cloudy"}` + weatherObj := &Monitor{ + ID: 2, + JsonData: weatherInfo, + Ts: time2, } - return itbl, nil + cherryProfile := Person{ + Name: "Cherry", + Age: 23, + IsStudent: true, + Courses: []string{"archaeology", "physics"}, + } + jsonData, err := json.Marshal(cherryProfile) + if err != nil { + return nil, nil, nil, err + } + cherryObj := &Monitor{ + ID: 3, + JsonData: string(jsonData), + Ts: time3, + } + + return tb, weatherObj, cherryObj, nil } func (c *client) write(data *table.Table) error { @@ -109,6 +155,36 @@ func (c *client) write(data *table.Table) error { if err != nil { return err } + log.Printf("affected rows: %d\n", resp.GetAffectedRows().GetValue()) return nil } + +func (c *client) writeObject(obj *Monitor) error { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + resp, err := c.client.WriteObject(ctx, obj) + if err != nil { + return err + } + + log.Printf("affected rows: %d\n", resp.GetAffectedRows().GetValue()) + return nil +} + +func (c *client) streamWriteObject(obj *Monitor) error { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + if err := c.client.StreamWriteObject(ctx, obj); err != nil { + return err + } + affected, err := c.client.CloseStream(ctx) + if err != nil { + return err + } + + log.Printf("affected rows: %d\n", affected.GetValue()) + return nil +} diff --git a/examples/object/main.go b/examples/object/main.go index 6057330..522849a 100644 --- a/examples/object/main.go +++ b/examples/object/main.go @@ -30,6 +30,16 @@ const ( database = "public" ) +type Monitor struct { + ID int64 `greptime:"tag;column:id;type:int64"` + Host string `greptime:"tag;column:host;type:string"` + Memory uint64 `greptime:"field;column:memory;type:uint64"` + Cpu float64 `greptime:"field;column:cpu;type:float64"` + Temperature int64 `greptime:"field;column:temperature;type:int64"` + Running bool `greptime:"field;column:running;type:boolean"` + Ts time.Time `greptime:"timestamp;column:ts;type:timestamp;precision:millisecond"` +} + type client struct { client *greptime.Client } @@ -48,16 +58,6 @@ func newClient() (*client, error) { return c, nil } -type Monitor struct { - ID int64 `greptime:"tag;column:id;type:int64"` - Host string `greptime:"tag;column:host;type:string"` - Memory uint64 `greptime:"field;column:memory;type:uint64"` - Cpu float64 `greptime:"field;column:cpu;type:float64"` - Temperature int64 `greptime:"field;column:temperature;type:int64"` - Running bool `greptime:"field;column:running;type:boolean"` - Ts time.Time `greptime:"timestamp;column:ts;type:timestamp;precision:millisecond"` -} - func (Monitor) TableName() string { return "monitors_with_tag" } @@ -128,11 +128,11 @@ func (c *client) streamWriteObject(data []Monitor) { defer cancel() if err := c.client.StreamWriteObject(ctx, data); err != nil { - log.Println(err) + log.Fatal(err) } affected, err := c.client.CloseStream(ctx) if err != nil { - log.Fatalln(err) + log.Fatal(err) } log.Printf("affected rows: %d\n", affected.GetValue()) } @@ -142,11 +142,11 @@ func (c *client) streamDeleteObject(data []Monitor) { defer cancel() if err := c.client.StreamDeleteObject(ctx, data); err != nil { - log.Println(err) + log.Fatal(err) } affected, err := c.client.CloseStream(ctx) if err != nil { - log.Fatalln(err) + log.Fatal(err) } log.Printf("affected rows: %d\n", affected.GetValue()) } @@ -154,7 +154,7 @@ func (c *client) streamDeleteObject(data []Monitor) { func main() { c, err := newClient() if err != nil { - log.Fatalf("failed to new client: %v:", err) + log.Fatalf("failed to new client: %v", err) } data := initData() diff --git a/examples/opentelemetry/main.go b/examples/opentelemetry/main.go index efd227a..0871498 100644 --- a/examples/opentelemetry/main.go +++ b/examples/opentelemetry/main.go @@ -122,15 +122,15 @@ func main() { c, err := newClient(tracerProvider, meterProvider) if err != nil { - log.Fatalf("failed to new client: %v:", err) + log.Fatalf("failed to new client: %v", err) } data, err := initData() if err != nil { - log.Fatalf("failed to init data: %v:", err) + log.Fatalf("failed to init data: %v", err) } if err = c.write(data[1]); err != nil { - log.Fatalf("failed to write data: %v:", err) + log.Fatalf("failed to write data: %v", err) } log.Printf("Sleep 30s...") diff --git a/examples/table/main.go b/examples/table/main.go index 4906163..1520973 100644 --- a/examples/table/main.go +++ b/examples/table/main.go @@ -62,76 +62,76 @@ func initData() []*table.Table { itbl, err := table.New("monitors_with_schema") if err != nil { - log.Println(err) + log.Fatal(err) } // add column at first. This is to define the schema of the table. if err := itbl.AddTagColumn("id", types.INT64); err != nil { - log.Println(err) + log.Fatal(err) } if err := itbl.AddFieldColumn("host", types.STRING); err != nil { - log.Println(err) + log.Fatal(err) } if err := itbl.AddFieldColumn("temperature", types.FLOAT); err != nil { - log.Println(err) + log.Fatal(err) } if err := itbl.AddTimestampColumn("timestamp", types.TIMESTAMP_MICROSECOND); err != nil { - log.Println(err) + log.Fatal(err) } if err := itbl.AddRow(1, "hello", 1.1, time1); err != nil { - log.Println(err) + log.Fatal(err) } if err := itbl.AddRow(2, "hello", 2.2, time2); err != nil { - log.Println(err) + log.Fatal(err) } if err := itbl.AddRow(3, "hello", 3.3, time3); err != nil { - log.Println(err) + log.Fatal(err) } utbl, err := table.New("monitors_with_schema") if err != nil { - log.Println(err) + log.Fatal(err) } // add column at first. This is to define the schema of the table. if err := utbl.AddTagColumn("id", types.INT64); err != nil { - log.Println(err) + log.Fatal(err) } if err := utbl.AddFieldColumn("host", types.STRING); err != nil { - log.Println(err) + log.Fatal(err) } if err := utbl.AddFieldColumn("temperature", types.FLOAT); err != nil { - log.Println(err) + log.Fatal(err) } if err := utbl.AddTimestampColumn("timestamp", types.TIMESTAMP_MICROSECOND); err != nil { - log.Println(err) + log.Fatal(err) } if err := utbl.AddRow(1, "hello", 1.2, time1); err != nil { - log.Println(err) + log.Fatal(err) } dtbl, err := table.New("monitors_with_schema") if err != nil { - log.Println(err) + log.Fatal(err) } // add column at first. This is to define the schema of the table. if err := dtbl.AddTagColumn("id", types.INT64); err != nil { - log.Println(err) + log.Fatal(err) } if err := dtbl.AddFieldColumn("host", types.STRING); err != nil { - log.Println(err) + log.Fatal(err) } if err := dtbl.AddFieldColumn("temperature", types.FLOAT); err != nil { - log.Println(err) + log.Fatal(err) } if err := dtbl.AddTimestampColumn("timestamp", types.TIMESTAMP_MICROSECOND); err != nil { - log.Println(err) + log.Fatal(err) } if err := dtbl.AddRow(3, "hello", 3.3, time3); err != nil { - log.Println(err) + log.Fatal(err) } return []*table.Table{itbl, utbl, dtbl} @@ -142,7 +142,7 @@ func (c *client) write(data *table.Table) { defer cancel() resp, err := c.client.Write(ctx, data) if err != nil { - log.Println(err) + log.Fatal(err) } log.Printf("affected rows: %d\n", resp.GetAffectedRows().GetValue()) } @@ -152,7 +152,7 @@ func (c *client) delete(data *table.Table) { defer cancel() resp, err := c.client.Delete(ctx, data) if err != nil { - log.Println(err) + log.Fatal(err) } log.Printf("affected rows: %d\n", resp.GetAffectedRows().GetValue()) } @@ -161,11 +161,11 @@ func (c *client) streamWrite(data *table.Table) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() if err := c.client.StreamWrite(ctx, data); err != nil { - log.Println(err) + log.Fatal(err) } affected, err := c.client.CloseStream(ctx) if err != nil { - log.Fatalln(err) + log.Fatal(err) } log.Printf("affected rows: %d\n", affected.GetValue()) } @@ -174,11 +174,11 @@ func (c *client) streamDelete(data *table.Table) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() if err := c.client.StreamDelete(ctx, data); err != nil { - log.Println(err) + log.Fatal(err) } affected, err := c.client.CloseStream(ctx) if err != nil { - log.Fatalln(err) + log.Fatal(err) } log.Printf("affected rows: %d\n", affected.GetValue()) } @@ -186,7 +186,7 @@ func (c *client) streamDelete(data *table.Table) { func main() { c, err := newClient() if err != nil { - log.Fatalf("failed to new client: %v:", err) + log.Fatalf("failed to new client: %v", err) } data := initData()