Skip to content

Commit

Permalink
refactor: ignore fields
Browse files Browse the repository at this point in the history
  • Loading branch information
daviderli614 committed Dec 10, 2024
1 parent 87d4cfd commit abb7821
Show file tree
Hide file tree
Showing 6 changed files with 477 additions and 12 deletions.
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ docker run --rm -p 4000-4003:4000-4003 \
- [opentelemetry](opentelemetry/README.md)
- [hints](hints/README.md)
- [jsondata](jsondata/README.md)
- [ignorefields](ignorefields/README.md)

## Query

Expand Down
44 changes: 44 additions & 0 deletions examples/ignorefields/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Insert data into GreptimeDB

When fields are marked with `greptime:"-"`, writing to these fields will be ignored.
```go
type Monitor struct {
ID int64 `greptime:"tag;column:id;type:int64"`
Host string `greptime:"tag;column:host;type:string"`
Memory uint64 `greptime:"-"`
Cpu float64 `greptime:"field;column:cpu;type:float64"`
Temperature int64 `greptime:"-"`
Running bool `greptime:"field;column:running;type:boolean"`
Ts time.Time `greptime:"timestamp;column:ts;type:timestamp;precision:millisecond"`
}
```

## Insert

```go
go run main.go
```

Output:

```log
2024/12/10 09:30:40 affected rows: 1
2024/12/10 09:30:40 affected rows: 1
```

## Query

Your can using [MySQL Client](https://docs.greptime.com/user-guide/protocols/mysql) to query the data from GreptimeDB.

```shell
$ mysql -h 127.0.0.1 -P 4002

mysql> select *from monitors_with_ignore_field;
+------+-----------+------+---------+----------------------------+
| id | host | cpu | running | ts |
+------+-----------+------+---------+----------------------------+
| 0 | 127.0.0.1 | 1.3 | 0 | 2024-12-10 09:30:40.709000 |
| 1 | 127.0.0.2 | 3.2 | 1 | 2024-12-10 09:30:40.709000 |
+------+-----------+------+---------+----------------------------+
2 rows in set (0.03 sec)
```
131 changes: 131 additions & 0 deletions examples/ignorefields/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// 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"
"log"
"time"

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

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

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

type Monitor struct {
ID int64 `greptime:"tag;column:id;type:int64"`
Host string `greptime:"tag;column:host;type:string"`
Memory uint64 `greptime:"-"`
Cpu float64 `greptime:"field;column:cpu;type:float64"`
Temperature int64 `greptime:"-"`
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
}

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 (Monitor) TableName() string {
return "monitors_with_ignore_field"
}

func initData() []Monitor {
return []Monitor{
{
ID: 0,
Host: "127.0.0.1",
Memory: 1,
Ts: time.Now(),
Cpu: 1.3,
Temperature: -1,
Running: false,
},
{
ID: 1,
Host: "127.0.0.2",
Memory: 2,
Ts: time.Now(),
Cpu: 3.2,
Temperature: 1,
Running: true,
},
}
}

func (c *client) writeObject(data []Monitor) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()

resp, err := c.client.WriteObject(ctx, data)
if err != nil {
return err
}

log.Printf("affected rows: %d\n", resp.GetAffectedRows().GetValue())
return nil
}

func (c *client) streamWriteObject(data []Monitor) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()

if err := c.client.StreamWriteObject(ctx, data); 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
}

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

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

if err = c.streamWriteObject(data[1:]); err != nil {
log.Fatalf("failed to stream write data: %v:", err)
}
}
4 changes: 4 additions & 0 deletions schema/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ func newColumnSchema(columnName string, semanticType gpb.SemanticType, datatype
func parseField(structField reflect.StructField) (*Field, error) {
tags := parseTag(structField)

if _, ok := tags["-"]; ok && len(tags) == 1 {
return nil, nil
}

columnName, err := util.SanitateName(structField.Name)
if err != nil {
return nil, err
Expand Down
24 changes: 12 additions & 12 deletions schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ func parseSchema(input any) (*Schema, error) {
if err != nil {
return nil, err
}
fields = append(fields, field.ToColumnSchema())
if field != nil {
fields = append(fields, field.ToColumnSchema())
}
}

return &Schema{tableName: tableName, fields: fields}, nil
Expand Down Expand Up @@ -142,25 +144,23 @@ func (s *Schema) parseValues(input any) error {
return fmt.Errorf("unsupported type %T of %+v", input, input)
}

size := len(reflect.VisibleFields(typ))
values := make([]*gpb.Value, 0, size)
for i, structField := range reflect.VisibleFields(typ) {
if !structField.IsExported() {
visibleFields := reflect.VisibleFields(typ)
size := make([]reflect.StructField, 0, len(visibleFields))
values := make([]*gpb.Value, 0, len(size))

for _, structField := range visibleFields {
if !structField.IsExported() || structField.Tag.Get("greptime") == "-" {
continue
}
size = append(size, structField)
}

for i, structField := range size {
field := s.fields[i]
value, err := parseValue(field.Datatype, val.FieldByName(structField.Name))
if err != nil {
return err
}
if structField.Tag.Get("greptime") == "-" {
zeroValue := reflect.Zero(structField.Type).Interface()
value, err = parseValue(field.Datatype, reflect.ValueOf(zeroValue))
if err != nil {
return err
}
}
values = append(values, value)
}

Expand Down
Loading

0 comments on commit abb7821

Please sign in to comment.