Skip to content

Commit

Permalink
feat: support json type
Browse files Browse the repository at this point in the history
  • Loading branch information
daviderli614 committed Nov 11, 2024
1 parent 5a19d5e commit 1267899
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 3 deletions.
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ package greptime
import (
"context"

gpb "github.com/GreptimeTeam/greptime-proto/go/greptime/v1"
"google.golang.org/grpc"

gpb "github.com/GreptimeTeam/greptime-proto/go/greptime/v1"
"github.com/GreptimeTeam/greptimedb-ingester-go/request"
"github.com/GreptimeTeam/greptimedb-ingester-go/request/header"
"github.com/GreptimeTeam/greptimedb-ingester-go/schema"
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ docker run --rm -p 4000-4003:4000-4003 \
- [healthcheck](healthcheck/README.md)
- [opentelemetry](opentelemetry/README.md)
- [hints](hints/README.md)
- [jsondata](jsondata/README.md)

## Query

Expand Down
Empty file added examples/jsondata/README.md
Empty file.
122 changes: 122 additions & 0 deletions examples/jsondata/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright 2024 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"context"
"encoding/json"
"fmt"
"log"
"time"

greptime "github.com/GreptimeTeam/greptimedb-ingester-go"
"github.com/GreptimeTeam/greptimedb-ingester-go/table"
"github.com/GreptimeTeam/greptimedb-ingester-go/table/types"
)

const (
// The GreptimeDB address.
host = "127.0.0.1"

// The database name.
database = "public"
)

type Person struct {
Name string
Age int
IsStudent bool
Courses []string
}

type client struct {
client *greptime.Client
}

func newClient() (*client, error) {
cfg := greptime.NewConfig(host).WithDatabase(database)

gtClient, err := greptime.NewClient(cfg)
if err != nil {
return nil, err
}

c := &client{
client: gtClient,
}

return c, nil
}

func main() {
c, err := newClient()
if err != nil {
log.Fatalf("failed to new client: %v:", err)
}

data, err := initData()
if err != nil {
log.Fatalf("failed to init data: %v:", err)
}
if err = c.write(data[0]); err != nil {
log.Fatalf("failed to write data: %v:", err)
}
}

func initData() ([]*table.Table, error) {
time1 := time.Now()

itbl, err := table.New("json_data")
if err != nil {
return nil, err
}
//jsonData := `{"key1":"value1","key2":10}`
//jsonStr2 := `{"name":"GreptimeDB","open_source":true}`
p := Person{
Name: "Jain Doe",
Age: 25,
IsStudent: false,
Courses: []string{"math", "history", "chemistry"},
}

jsonData, err := json.Marshal(p)
if err != nil {
fmt.Println("Error:", err)
return nil, err
}
// 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 := itbl.AddTimestampColumn("timestamp", types.TIMESTAMP_MICROSECOND); err != nil {
return nil, err
}
if err := itbl.AddRow(string(jsonData), time1); err != nil {
return nil, err
}

return []*table.Table{itbl}, nil
}

func (c client) write(data *table.Table) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
resp, err := c.client.Write(ctx, data)
if err != nil {
return err
}
log.Printf("affected rows: %d\n", resp.GetAffectedRows().GetValue())
return nil
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/GreptimeTeam/greptimedb-ingester-go
go 1.20

require (
github.com/GreptimeTeam/greptime-proto v0.7.0
github.com/GreptimeTeam/greptime-proto v0.9.0
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/stoewer/go-strcase v1.3.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/GreptimeTeam/greptime-proto v0.7.0 h1:WHBjAu+NWDFcbZgW9kPtksxEKEAeqYemP1HY63QuO48=
github.com/GreptimeTeam/greptime-proto v0.7.0/go.mod h1:jk5XBR9qIbSBiDF2Gix1KALyIMCVktcpx91AayOWxmE=
github.com/GreptimeTeam/greptime-proto v0.9.0 h1:UC2vhGEQun75aejAyr6SdHTMjHBM5dlSMDr72ue0U8Y=
github.com/GreptimeTeam/greptime-proto v0.9.0/go.mod h1:jk5XBR9qIbSBiDF2Gix1KALyIMCVktcpx91AayOWxmE=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
Expand Down
8 changes: 7 additions & 1 deletion schema/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,15 @@ func parseValue(typ gpb.ColumnDataType, val reflect.Value) (*gpb.Value, error) {
// TODO(yuanbohan): support decimal 128
case gpb.ColumnDataType_DECIMAL128:
return nil, fmt.Errorf("DECIMAL 128 not supported for %#v", val)

case gpb.ColumnDataType_JSON:
if val.Kind() != reflect.String {
return nil, fmt.Errorf("%#v is not compatible with String", val)
}
return cell.New(val.String(), typ).Build()

default:
return nil, fmt.Errorf("unknown column data type: %v", typ)

}
}

Expand Down
14 changes: 14 additions & 0 deletions table/cell/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,17 @@ func BuildTimeNanosecond(v any) (*gpb.Value, error) {

return &gpb.Value{ValueData: &gpb.Value_TimeNanosecondValue{TimeNanosecondValue: val}}, nil
}

func BuildJSON(v any) (*gpb.Value, error) {
var val string
switch t := v.(type) {
case string:
val = t
case *string:
val = *t
default:
return nil, fmt.Errorf(formatter+"string", t, v)
}

return &gpb.Value{ValueData: &gpb.Value_StringValue{StringValue: val}}, nil
}
3 changes: 3 additions & 0 deletions table/cell/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ func (c Cell) Build() (*gpb.Value, error) {
// TODO(yuanbohan): support decimal 128
case gpb.ColumnDataType_DECIMAL128:
return nil, fmt.Errorf("DECIMAL 128 not supported for %#v", c.Val)

case gpb.ColumnDataType_JSON:
return BuildJSON(c.Val)
default:
return nil, fmt.Errorf("unknown column data type: %v", c.DataType)
}
Expand Down
8 changes: 8 additions & 0 deletions table/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ const (
// INTERVAL_MONTH_DAY_NANO ColumnType = 25
// DECIMAL128 ColumnType = 30

JSON ColumnType = 31

// the following types are not from protocol buffer
INT ColumnType = 101
UINT ColumnType = 102
Expand Down Expand Up @@ -146,6 +148,8 @@ func (type_ ColumnType) String() string {
return "TIMESTAMP_MICROSECOND"
case TIMESTAMP_NANOSECOND:
return "TIMESTAMP_NANOSECOND"
case JSON:
return "JSON"
default:
return "UNKNOWN"
}
Expand Down Expand Up @@ -193,6 +197,8 @@ func ParseColumnType(type_, precision string) (gpb.ColumnDataType, error) {
return gpb.ColumnDataType_TIMESTAMP_MICROSECOND, nil
case TIMESTAMP_NANOSECOND.String():
return gpb.ColumnDataType_TIMESTAMP_NANOSECOND, nil
case JSON.String():
return gpb.ColumnDataType_JSON, nil
default:
return 0, fmt.Errorf("parse: unsupported column type %q", type_)
}
Expand Down Expand Up @@ -238,6 +244,8 @@ func ConvertType(type_ ColumnType) (gpb.ColumnDataType, error) {
return gpb.ColumnDataType_TIMESTAMP_MICROSECOND, nil
case TIMESTAMP_NANOSECOND:
return gpb.ColumnDataType_TIMESTAMP_NANOSECOND, nil
case JSON:
return gpb.ColumnDataType_JSON, nil
default:
return 0, fmt.Errorf("convert: unsupported column type %q", type_.String())
}
Expand Down

0 comments on commit 1267899

Please sign in to comment.