github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/entity/columns_json.go (about)

     1  package entity
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"github.com/cockroachdb/errors"
     9  	schema "github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
    10  )
    11  
    12  var _ (Column) = (*ColumnJSONBytes)(nil)
    13  
    14  // ColumnJSONBytes column type for JSON.
    15  // all items are marshaled json bytes.
    16  type ColumnJSONBytes struct {
    17  	ColumnBase
    18  	name      string
    19  	values    [][]byte
    20  	isDynamic bool
    21  }
    22  
    23  // Name returns column name.
    24  func (c *ColumnJSONBytes) Name() string {
    25  	return c.name
    26  }
    27  
    28  // Type returns column FieldType.
    29  func (c *ColumnJSONBytes) Type() FieldType {
    30  	return FieldTypeJSON
    31  }
    32  
    33  // Len returns column values length.
    34  func (c *ColumnJSONBytes) Len() int {
    35  	return len(c.values)
    36  }
    37  
    38  func (c *ColumnJSONBytes) Slice(start, end int) Column {
    39  	l := c.Len()
    40  	if start > l {
    41  		start = l
    42  	}
    43  	if end == -1 || end > l {
    44  		end = l
    45  	}
    46  	return &ColumnJSONBytes{
    47  		ColumnBase: c.ColumnBase,
    48  		name:       c.name,
    49  		values:     c.values[start:end],
    50  	}
    51  }
    52  
    53  // Get returns value at index as interface{}.
    54  func (c *ColumnJSONBytes) Get(idx int) (interface{}, error) {
    55  	if idx < 0 || idx > c.Len() {
    56  		return nil, errors.New("index out of range")
    57  	}
    58  	return c.values[idx], nil
    59  }
    60  
    61  func (c *ColumnJSONBytes) GetAsString(idx int) (string, error) {
    62  	bs, err := c.ValueByIdx(idx)
    63  	if err != nil {
    64  		return "", err
    65  	}
    66  	return string(bs), nil
    67  }
    68  
    69  // FieldData return column data mapped to schema.FieldData.
    70  func (c *ColumnJSONBytes) FieldData() *schema.FieldData {
    71  	fd := &schema.FieldData{
    72  		Type:      schema.DataType_JSON,
    73  		FieldName: c.name,
    74  		IsDynamic: c.isDynamic,
    75  	}
    76  
    77  	fd.Field = &schema.FieldData_Scalars{
    78  		Scalars: &schema.ScalarField{
    79  			Data: &schema.ScalarField_JsonData{
    80  				JsonData: &schema.JSONArray{
    81  					Data: c.values,
    82  				},
    83  			},
    84  		},
    85  	}
    86  
    87  	return fd
    88  }
    89  
    90  // ValueByIdx returns value of the provided index.
    91  func (c *ColumnJSONBytes) ValueByIdx(idx int) ([]byte, error) {
    92  	if idx < 0 || idx >= c.Len() {
    93  		return nil, errors.New("index out of range")
    94  	}
    95  	return c.values[idx], nil
    96  }
    97  
    98  // AppendValue append value into column.
    99  func (c *ColumnJSONBytes) AppendValue(i interface{}) error {
   100  	var v []byte
   101  	switch raw := i.(type) {
   102  	case []byte:
   103  		v = raw
   104  	default:
   105  		k := reflect.TypeOf(i).Kind()
   106  		if k == reflect.Ptr {
   107  			k = reflect.TypeOf(i).Elem().Kind()
   108  		}
   109  		switch k {
   110  		case reflect.Struct:
   111  			fallthrough
   112  		case reflect.Map:
   113  			bs, err := json.Marshal(raw)
   114  			if err != nil {
   115  				return err
   116  			}
   117  			v = bs
   118  		default:
   119  			return fmt.Errorf("expect json compatible type([]byte, struct[}, map], got %T)", i)
   120  		}
   121  	}
   122  	c.values = append(c.values, v)
   123  
   124  	return nil
   125  }
   126  
   127  // Data returns column data.
   128  func (c *ColumnJSONBytes) Data() [][]byte {
   129  	return c.values
   130  }
   131  
   132  func (c *ColumnJSONBytes) WithIsDynamic(isDynamic bool) *ColumnJSONBytes {
   133  	c.isDynamic = isDynamic
   134  	return c
   135  }
   136  
   137  // NewColumnJSONBytes composes a Column with json bytes.
   138  func NewColumnJSONBytes(name string, values [][]byte) *ColumnJSONBytes {
   139  	return &ColumnJSONBytes{
   140  		name:   name,
   141  		values: values,
   142  	}
   143  }