gtly

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2022 License: Apache-2.0 Imports: 10 Imported by: 6

README

gtly - Dynamic data structure with go lang.

GoReportCard GoDoc

This library is compatible with Go 1.15+

Please refer to CHANGELOG.md if you encounter breaking changes.

Motivation

The goal of this project is to use dynamic data types without defining native GO structs with minimum memory footprint. Alternative would be just using map, but that is way too inefficient. Having dynamic type safe objects enables building generic solution for REST/Micro Service/ETL etc. To build dynamic solution dynamic object should be easily transferable into common format like JSON, AVRO, ProtoBuf, etc....

Introduction

Gtly complex data type use runtime struct based storage with Proto reference to reduce memory footprint and to avoid reflection. An proto instance is shared across all Object and Collection of the same type. Proto control mapping between field and field position withing object, or slice item. What's more proto field define field meta data like DateLayout, OutputName controlled by proto CaseFormat dynamically.

Usage

Object
package mypacakge

import (
	"fmt"
	"github.com/viant/gtly"
    "github.com/viant/toolbox/format"
	"github.com/viant/gtly/codec/json"
	"log"
	"time"
)

func NewObject_Usage() {
  fooProvider, err := gtly.NewProvider("foo",
    gtly.NewField("id", gtly.FieldTypeInt),
    gtly.NewField("firsName", gtly.FieldTypeString),
    gtly.NewField("description", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
    gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt("2006-01-02T15:04:05Z07:00")),
    gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
  )
  if err != nil {
    log.Fatal(err)
  }
  foo1 := fooProvider.NewObject()
  foo1.SetValue("id", 1)
  foo1.SetValue("firsName", "Adam")
  foo1.SetValue("updated", time.Now())
  foo1.SetValue("numbers", []int{1, 2, 3})

  JSON, err := json.Marshal(foo1)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", JSON)
  fooProvider.OutputCaseFormat(format.CaseLower, format.CaseUpperUnderscore)
  JSON, _ = json.Marshal(foo1)
  fmt.Printf("%s\n", JSON)

  fooProvider.OutputCaseFormat(format.CaseLower, format.CaseLowerUnderscore)
  foo1.SetValue("active", true)
  foo1.SetValue("description", "some description")

  JSON, _ = json.Marshal(foo1)
  fmt.Printf("%s\n", JSON)
}
Array
package mypacakge

import (
	"fmt"
	"github.com/viant/gtly"
	"github.com/viant/gtly/codec/json"
	"log"
	"time"
)

func NewArray_Usage() {
  fooProvider, err := gtly.NewProvider("foo",
    gtly.NewField("id", gtly.FieldTypeInt),
    gtly.NewField("firsName", gtly.FieldTypeString),
    gtly.NewField("income", gtly.FieldTypeFloat64),
    gtly.NewField("description", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
    gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt(time.RFC3339)),
    gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
  )
  if err != nil {
    log.Fatal(err)
  }
  fooArray1 := fooProvider.NewArray()

  setId := fooProvider.Mutator("id")
  setIncome := fooProvider.Mutator("income")
  setFirstName := fooProvider.Mutator("firsName")

  for i := 0; i < 10; i++ {
    foo1 := fooProvider.NewObject()
    setId.Int(foo1, 1)
    setIncome.Float64(foo1, 64000.0*float64(1+(10/(i+1))))
    setFirstName.String(foo1, "Adam")
    fooArray1.AddObject(foo1)
  }

  now := time.Now()
  fooArray1.Add(map[string]interface{}{
    "id":       100,
    "firsName": "Tom",
    "updated":  now,
  })

  totalIncome := 0.0
  incomeField := fooProvider.Proto.Accessor("income")
  //Iterating collection

  err = fooArray1.Objects(func(object *gtly.Object) (bool, error) {
    fmt.Printf("id: %v\n", object.Value("id"))
    fmt.Printf("name: %v\n", object.Value("name"))
    value := incomeField.Float64(object)
    totalIncome += value
    return true, nil
  })
  fmt.Printf("income total: %v\n", totalIncome)
  if err != nil {
    log.Fatal(err)
  }
  JSON, err := json.Marshal(fooArray1)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s", JSON)
}

Map
package mypacakge

import (
	"fmt"
	"github.com/viant/gtly"
	"github.com/viant/gtly/codec/json"
	"log"
	"time"
)

func NewMap_Usage() {
  fooProvider, err := gtly.NewProvider("foo",
    gtly.NewField("id", gtly.FieldTypeInt),
    gtly.NewField("firsName", gtly.FieldTypeString),
    gtly.NewField("description", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
    gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt(time.RFC3339)),
    gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
  )
  if err != nil {
    log.Fatal(err)
  }

  //Creates a map keyed by id Field
  aMap := fooProvider.NewMap(gtly.NewKeyProvider("id"))
  for i := 0; i < 10; i++ {
    foo := fooProvider.NewObject()
    foo.SetValue("id", i)
    foo.SetValue("firsName", fmt.Sprintf("Name %v", i))
    aMap.AddObject(foo)
  }

  //Accessing map
  foo1 := aMap.Object("1")
  JSON, err := json.Marshal(foo1)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", JSON)

  //Iterating map
  err = aMap.Pairs(func(key interface{}, item *gtly.Object) (bool, error) {
    fmt.Printf("id: %v\n", item.Value("id"))
    fmt.Printf("name: %v\n", item.Value("name"))
    return true, nil
  })
  if err != nil {
    log.Fatal(err)
  }

  JSON, err = json.Marshal(aMap)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", JSON)
  //[{"id":1,"firsName":"Name 1","updated":null,"numbers":null},{"id":3,"firsName":"Name 3","updated":null,"numbers":null},{"id":4,"firsName":"Name 4","updated":null,"numbers":null},{"id":6,"firsName":"Name 6","updated":null,"numbers":null},{"id":8,"firsName":"Name 8","updated":null,"numbers":null},{"id":9,"firsName":"Name 9","updated":null,"numbers":null},{"id":0,"firsName":"Name 0","updated":null,"numbers":null},{"id":2,"firsName":"Name 2","updated":null,"numbers":null},{"id":5,"firsName":"Name 5","updated":null,"numbers":null},{"id":7,"firsName":"Name 7","updated":null,"numbers":null}]
}
MultiMap
func NewMultiMap_Usage() {
  fooProvider, err := gtly.NewProvider("foo",
    gtly.NewField("id", gtly.FieldTypeInt),
    gtly.NewField("firsName", gtly.FieldTypeString),
    gtly.NewField("city", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
    gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt(time.RFC3339)),
    gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
    )
  if err != nil {
     log.Fatal(err)
  }
  
  //Creates a multi map keyed by id Field
  aMap := fooProvider.NewMultimap(gtly.NewKeyProvider("city"))
  for i := 0; i < 10; i++ {
    foo := fooProvider.NewObject()
    foo.SetValue("id", i)
    foo.SetValue("firsName", fmt.Sprintf("Name %v", i))
    if i%2 == 0 {
        foo.SetValue("city", "Cracow")
    } else {
        foo.SetValue("city", "Warsaw")
    }
    aMap.AddObject(foo)
  }
  
  //Accessing map
  fooInWarsawSlice := aMap.Slice("Warsaw")
  JSON, err := json.Marshal(fooInWarsawSlice)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", JSON)
  //Prints [{"id":1,"firsName":"Name 1","city":"Warsaw","updated":null,"numbers":null},{"id":3,"firsName":"Name 3","city":"Warsaw","updated":null,"numbers":null},{"id":5,"firsName":"Name 5","city":"Warsaw","updated":null,"numbers":null},{"id":7,"firsName":"Name 7","city":"Warsaw","updated":null,"numbers":null},{"id":9,"firsName":"Name 9","city":"Warsaw","updated":null,"numbers":null}]
  
  //Iterating multi map
  err = aMap.Slices(func(key interface{}, value *gtly.Array) (bool, error) {
    fmt.Printf("%v -> %v\n", key, value.Size())
    return true, nil
  })
  if err != nil {
    log.Fatal(err)
  }
  
  JSON, err = json.Marshal(aMap)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", JSON)
  //[{"id":0,"firsName":"Name 0","city":"Cracow","updated":null,"numbers":null},{"id":2,"firsName":"Name 2","city":"Cracow","updated":null,"numbers":null},{"id":4,"firsName":"Name 4","city":"Cracow","updated":null,"numbers":null},{"id":6,"firsName":"Name 6","city":"Cracow","updated":null,"numbers":null},{"id":8,"firsName":"Name 8","city":"Cracow","updated":null,"numbers":null},{"id":1,"firsName":"Name 1","city":"Warsaw","updated":null,"numbers":null},{"id":3,"firsName":"Name 3","city":"Warsaw","updated":null,"numbers":null},{"id":5,"firsName":"Name 5","city":"Warsaw","updated":null,"numbers":null},{"id":7,"firsName":"Name 7","city":"Warsaw","updated":null,"numbers":null},{"id":9,"firsName":"Name 9","city":"Warsaw","updated":null,"numbers":null}]

}

Contributing to gtly

Gtly is an open source project and contributors are welcome!

See TODO list

License

The source code is made available under the terms of the Apache License, Version 2, as stated in the file LICENSE.

Individual files may be made available under their own specific license, all compatible with Apache License, Version 2. Please see individual files for details.

Credits and Acknowledgements

Library Author: Adrian Witas

Documentation

Overview

Package gtly defines generic data types

To reduce memory footprint and to avoid reflection, slice position based storage is used with shared proto object. Proto object controls conversion between Field and Field position withing given object, slice item

Index

Examples

Constants

View Source
const (
	//FieldTypeInt int type
	FieldTypeInt = "int"
	//FieldTypeInt64 int type
	FieldTypeInt64 = "int64"
	//FieldTypeFloat32 float type
	FieldTypeFloat32 = "float32"
	//FieldTypeFloat64 float type
	FieldTypeFloat64 = "float64"
	//FieldTypeBool bool type
	FieldTypeBool = "bool"
	//FieldTypeString string type
	FieldTypeString = "string"
	//FieldTypeTime time type
	FieldTypeTime = "time"
	//FieldTypeBytes bytes type
	FieldTypeBytes = "bytes"
	//FieldTypeArray array type
	FieldTypeArray = "array"
	//FieldTypeObject object type
	FieldTypeObject = "object"
)

Variables

View Source
var NilValue = make([]*interface{}, 1)[0]

NilValue is used to discriminate between unset fileds, and set filed with nil value (for REST patch operation)

Functions

func Value

func Value(value interface{}) interface{}

Value returns value

Types

type Accessor added in v0.2.0

type Accessor struct {
	*xunsafe.Field
	// contains filtered or unexported fields
}

Accessor represents object mutator

func (*Accessor) Bool added in v0.2.0

func (m *Accessor) Bool(object *Object) bool

Bool returns bool value

func (*Accessor) Bytes added in v0.2.0

func (m *Accessor) Bytes(object *Object) []byte

Bytes returns []byte value

func (*Accessor) Float32 added in v0.2.0

func (m *Accessor) Float32(object *Object) float32

Float32 returns float32 value

func (*Accessor) Float64 added in v0.2.0

func (m *Accessor) Float64(object *Object) float64

Float64 returns float64 value

func (*Accessor) Int added in v0.2.0

func (m *Accessor) Int(object *Object) int

Int returns int value

func (*Accessor) Int64 added in v0.2.0

func (m *Accessor) Int64(object *Object) int64

Int64 returns int64 value

func (*Accessor) String added in v0.2.0

func (m *Accessor) String(object *Object) string

String returns string value

func (*Accessor) StringPtr added in v0.2.0

func (m *Accessor) StringPtr(object *Object) *string

StringPtr returns *string value

func (*Accessor) Time added in v0.2.0

func (m *Accessor) Time(object *Object) time.Time

Time returns time value

func (*Accessor) TimePtr added in v0.2.0

func (m *Accessor) TimePtr(object *Object) *time.Time

TimePtr returns *time.Time value

func (*Accessor) Value added in v0.2.0

func (m *Accessor) Value(object *Object) interface{}

Value returns value

type Array

type Array struct {
	// contains filtered or unexported fields
}

Array represents dynamic object slice

func (*Array) Add

func (a *Array) Add(value map[string]interface{}) error

Add adds object

func (*Array) AddObject

func (a *Array) AddObject(object *Object)

AddObject add elements to a slice

func (*Array) First

func (a *Array) First() *Object

First returns the first element on the slice

func (*Array) Objects

func (a *Array) Objects(handler func(item *Object) (bool, error)) error

Objects call handler for every object in this collection

func (*Array) Proto

func (a *Array) Proto() *Proto

Proto returns slice proto

func (*Array) Range

func (a *Array) Range(handler func(item interface{}) (bool, error)) error

Range calls handler with every slice element

func (*Array) Size

func (a *Array) Size() int

Size return slice size

type Collection

type Collection interface {
	//Add adds item to collection
	Add(values map[string]interface{}) error
	//AddObject add an object
	AddObject(object *Object)
	//Range calls handler with collection item
	Range(handler func(item interface{}) (toContinue bool, err error)) error
	//Objects calls handler with collection item object
	Objects(handler func(item *Object) (toContinue bool, err error)) error
	//Size returns collection size
	Size() int
	//Proto return collection component prototype
	Proto() *Proto
	//First returns first object
	First() *Object
}

Collection represents generic collection

type Field

type Field struct {
	Name          string `json:",omitempty"`
	Index         int
	StructTag     reflect.StructTag
	OmitEmpty     *bool        `json:",omitempty"`
	DateFormat    string       `json:",omitempty"`
	DataLayout    string       `json:",omitempty"`
	DataType      string       `json:",omitempty"`
	InputName     string       `json:",omitempty"`
	ComponentType string       `json:",omitempty"`
	Type          reflect.Type `json:"-"`
	// contains filtered or unexported fields
}

Field represents dynamic filed

func NewField

func NewField(name, dataType string, options ...Option) *Field

NewField creates new fields

func (*Field) Get

func (f *Field) Get(values []interface{}) interface{}

Get returns Field value

func (*Field) OutputName

func (f *Field) OutputName() string

OutputName returns Field output Name

func (*Field) SetProvider

func (f *Field) SetProvider(provider *Provider)

SetProvider set provider

func (*Field) ShallOmitEmpty

func (f *Field) ShallOmitEmpty() bool

ShallOmitEmpty return true if shall omit empty

func (*Field) TimeLayout

func (f *Field) TimeLayout() string

TimeLayout returns timelayout

type Fields added in v0.2.0

type Fields []*Field

Fields represents a fields

func MapFields added in v0.2.0

func MapFields(source interface{}) (Fields, error)

MapFields creates fields for supplied values

type Index

type Index func(values interface{}) string

Index represents Index function

func NewIndex

func NewIndex(keys []string) Index

NewIndex returns an Index for supplied keys

type KeyProvider added in v0.2.0

type KeyProvider func(o *Object) interface{}

KeyProvider represents a key provider

func NewKeyProvider added in v0.2.0

func NewKeyProvider(fieldName string) KeyProvider

NewKeyProvider creates a key provider

type Map

type Map struct {
	// contains filtered or unexported fields
}

Map represents generic map

func (*Map) Add

func (m *Map) Add(values map[string]interface{}) error

Add adds object from a map

func (*Map) AddObject

func (m *Map) AddObject(obj *Object)

AddObject adds object

func (*Map) First

func (m *Map) First() *Object

First return the first map elements

func (*Map) Object

func (m *Map) Object(key interface{}) *Object

Object returns an object for specified key or nil

func (*Map) Objects

func (m *Map) Objects(handler func(item *Object) (bool, error)) error

Objects call handler for every object in this collection

func (*Map) Pairs

func (m *Map) Pairs(handler func(key interface{}, item *Object) (bool, error)) error

Pairs iterate over object slice, any update to objects are applied to the slice

func (*Map) Proto

func (m *Map) Proto() *Proto

Proto returns map proto

func (*Map) PutObject added in v0.2.0

func (m *Map) PutObject(key interface{}, object *Object)

PutObject add object to the map

func (*Map) Range

func (m *Map) Range(handler func(item interface{}) (bool, error)) error

Range calls handler with every slice element

func (*Map) Size

func (m *Map) Size() int

Size return map size

type Multimap

type Multimap struct {
	// contains filtered or unexported fields
}

Multimap represents generic multi map

func (*Multimap) Add

func (m *Multimap) Add(values map[string]interface{}) error

Add add item to a map

func (*Multimap) AddObject

func (m *Multimap) AddObject(o *Object)

AddObject add object into multimap

func (*Multimap) First

func (m *Multimap) First() *Object

First returns an element from multimap

func (*Multimap) IsNil

func (m *Multimap) IsNil() bool

IsNil returns true if it's nil

func (*Multimap) Objects

func (m *Multimap) Objects(handler func(item *Object) (bool, error)) error

Objects call handler for every object in this collection

func (*Multimap) Proto

func (m *Multimap) Proto() *Proto

Proto returns multimap proto

func (*Multimap) Range

func (m *Multimap) Range(handler func(item interface{}) (bool, error)) error

Range calls handler with every slice element

func (*Multimap) Size

func (m *Multimap) Size() int

Size return slice size

func (*Multimap) Slice

func (m *Multimap) Slice(key string) *Array

Slice returns a slice for specified key or nil

func (*Multimap) Slices

func (m *Multimap) Slices(handler func(key interface{}, value *Array) (bool, error)) error

Slices iterate over object slice, any update to objects are applied to the slice

type Mutator added in v0.2.0

type Mutator struct {
	*xunsafe.Field
	// contains filtered or unexported fields
}

Mutator represents object mutator

func (*Mutator) Bool added in v0.2.0

func (m *Mutator) Bool(object *Object, value bool)

Bool sets bool value

func (*Mutator) Bytes added in v0.2.0

func (m *Mutator) Bytes(object *Object, value []byte)

Bytes sets []byte value

func (*Mutator) Float32 added in v0.2.0

func (m *Mutator) Float32(object *Object, value float32)

Float32 sets float32 value

func (*Mutator) Float64 added in v0.2.0

func (m *Mutator) Float64(object *Object, value float64)

Float64 sets float64 value

func (*Mutator) Int added in v0.2.0

func (m *Mutator) Int(object *Object, value int)

Int sets int value

func (*Mutator) Int64 added in v0.2.0

func (m *Mutator) Int64(object *Object, value int64)

Int64 sets int64 value

func (*Mutator) SetValue added in v0.2.0

func (m *Mutator) SetValue(object *Object, value interface{})

SetValue sets value

func (*Mutator) String added in v0.2.0

func (m *Mutator) String(object *Object, value string)

String sets string value

func (*Mutator) StringPtr added in v0.2.0

func (m *Mutator) StringPtr(object *Object, value *string)

StringPtr sets *string value

func (*Mutator) Time added in v0.2.0

func (m *Mutator) Time(object *Object, value time.Time)

Time sets time value

func (*Mutator) TimePtr added in v0.2.0

func (m *Mutator) TimePtr(object *Object, value *time.Time)

TimePtr sets time value

type Nilable

type Nilable interface {
	IsNil() bool
}

Nilable represent a type that can be nil

type Object

type Object struct {
	// contains filtered or unexported fields
}

Object represents dynamic object

func (*Object) Addr added in v0.2.0

func (o *Object) Addr() unsafe.Pointer

Addr returns struct unsafe pointer

func (*Object) AsMap

func (o *Object) AsMap() map[string]interface{}

AsMap return map

func (*Object) Field added in v0.2.0

func (o *Object) Field(name string) *Field

Field returns Field by name

func (*Object) FieldOutputName added in v0.2.0

func (o *Object) FieldOutputName(field *Field) string

FieldOutputName returns Field output name

func (*Object) Interface added in v0.2.0

func (o *Object) Interface() interface{}

Interface returns a struct value

func (*Object) IsNil

func (o *Object) IsNil() bool

IsNil returns true if object is nil

func (*Object) Proto

func (o *Object) Proto() *Proto

Proto returns object proto

func (*Object) Set added in v0.2.0

func (o *Object) Set(val interface{}) error

Set sets a value from a map of a slice (slice index has to match field index)

func (*Object) SetAt added in v0.2.0

func (o *Object) SetAt(index int) bool

SetAt returns true if value was set at given index

func (*Object) SetValue

func (o *Object) SetValue(fieldName string, value interface{})

SetValue sets fieldValues

func (*Object) SetValueAt added in v0.2.0

func (o *Object) SetValueAt(fieldIndex int, value interface{})

SetValueAt sets field's value

func (*Object) Value

func (o *Object) Value(fieldName string) interface{}

Value get value for supplied filed name

func (*Object) ValueAt

func (o *Object) ValueAt(fieldIndex int) (interface{}, bool)

ValueAt get value for supplied filed Index

type Option

type Option func(field *Field)

Option represents Field option

func ComponentTypeOpt

func ComponentTypeOpt(componentType string) Option

ComponentTypeOpt return a Field component type option

func DateLayoutOpt

func DateLayoutOpt(layout string) Option

DateLayoutOpt Field with data layout option

func OmitEmptyOpt

func OmitEmptyOpt(omitEmpty bool) Option

OmitEmptyOpt returns a Field omit empty option

func ProviderOpt

func ProviderOpt(provider *Provider) Option

ProviderOpt return a Field provider option

func ValueOpt added in v0.2.0

func ValueOpt(value interface{}) (Option, error)

ValueOpt derives type from supplied value

type Proto

type Proto struct {
	Name string

	OmitEmpty bool
	// contains filtered or unexported fields
}

Proto represents generic type prototype

func (*Proto) Accessor added in v0.2.0

func (p *Proto) Accessor(fieldName string) *Accessor

Accessor returns a field accessor

func (*Proto) AccessorAt added in v0.2.0

func (p *Proto) AccessorAt(index int) *Accessor

AccessorAt returns a field accessor

func (*Proto) Field

func (p *Proto) Field(name string) *Field

Field returns Field for specified Name

func (*Proto) FieldAt added in v0.2.0

func (p *Proto) FieldAt(index int) *Field

FieldAt returns Field at position

func (*Proto) Fields

func (p *Proto) Fields() []Field

Fields returns fields list

func (*Proto) Hide

func (p *Proto) Hide(name string)

Hide set hidden flag for the Field

func (*Proto) InputCaseFormat

func (p *Proto) InputCaseFormat(source, input format.Case) error

InputCaseFormat set output case format

func (*Proto) Mutator added in v0.2.0

func (p *Proto) Mutator(fieldName string) *Mutator

Mutator returns field mutator

func (*Proto) MutatorAt added in v0.2.0

func (p *Proto) MutatorAt(index int) *Mutator

MutatorAt returns field mutator

func (*Proto) OutputCaseFormat

func (p *Proto) OutputCaseFormat(source, output format.Case) error

OutputCaseFormat set output case format

func (*Proto) SetEmptyValues

func (p *Proto) SetEmptyValues(values ...interface{})

SetEmptyValues sets empty values, use only if empty values are non in default map: nil, empty string

func (*Proto) SetOmitEmpty

func (p *Proto) SetOmitEmpty(omitEmpty bool)

SetOmitEmpty sets omit empty flag

func (*Proto) Show

func (p *Proto) Show(name string)

Show remove hidden flag for supplied Field

func (*Proto) SimpleName

func (p *Proto) SimpleName() string

SimpleName returns simple name

func (*Proto) Size

func (p *Proto) Size() int

Size returns proto size

func (*Proto) Type added in v0.2.0

func (p *Proto) Type() reflect.Type

Type returns proto data type

type Provider

type Provider struct {
	*Proto
}

Provider provides shares proto data across all dynamic types

func NewProvider

func NewProvider(name string, fields ...*Field) (*Provider, error)

NewProvider creates provider

func (*Provider) NewArray

func (p *Provider) NewArray(items ...*Object) *Array

NewArray creates a slice

Example

TestProvider_NewArray new array example

package main

import (
	"fmt"
	"github.com/viant/gtly"
	"github.com/viant/gtly/codec/json"
	"log"
	"time"
)

func main() {
	fooProvider, err := gtly.NewProvider("foo",
		gtly.NewField("id", gtly.FieldTypeInt),
		gtly.NewField("firsName", gtly.FieldTypeString),
		gtly.NewField("income", gtly.FieldTypeFloat64),
		gtly.NewField("description", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
		gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt(time.RFC3339)),
		gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
	)
	if err != nil {
		log.Fatal(err)
	}
	fooArray1 := fooProvider.NewArray()

	setId := fooProvider.Mutator("id")
	setIncome := fooProvider.Mutator("income")
	setFirstName := fooProvider.Mutator("firsName")

	for i := 0; i < 10; i++ {
		foo1 := fooProvider.NewObject()
		setId.Int(foo1, 1)
		setIncome.Float64(foo1, 64000.0*float64(1+(10/(i+1))))
		setFirstName.String(foo1, "Adam")
		fooArray1.AddObject(foo1)
	}

	now := time.Now()
	fooArray1.Add(map[string]interface{}{
		"id":       100,
		"firsName": "Tom",
		"updated":  now,
	})

	totalIncome := 0.0
	incomeField := fooProvider.Proto.Accessor("income")
	//Iterating collection

	err = fooArray1.Objects(func(object *gtly.Object) (bool, error) {
		fmt.Printf("id: %v\n", object.Value("id"))
		fmt.Printf("name: %v\n", object.Value("name"))
		value := incomeField.Float64(object)
		totalIncome += value
		return true, nil
	})
	fmt.Printf("income total: %v\n", totalIncome)
	if err != nil {
		log.Fatal(err)
	}
	JSON, err := json.Marshal(fooArray1)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", JSON)
}
Output:

func (*Provider) NewMap

func (p *Provider) NewMap(keyProvider KeyProvider) *Map

NewMap creates a map of string and object

Example

ExampleProvider_NewMap new map example

package main

import (
	"fmt"
	"github.com/viant/gtly"
	"github.com/viant/gtly/codec/json"
	"log"
	"time"
)

func main() {

	fooProvider, err := gtly.NewProvider("foo",
		gtly.NewField("id", gtly.FieldTypeInt),
		gtly.NewField("firsName", gtly.FieldTypeString),
		gtly.NewField("description", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
		gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt(time.RFC3339)),
		gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
	)
	if err != nil {
		log.Fatal(err)
	}

	//Creates a map keyed by id Field
	aMap := fooProvider.NewMap(gtly.NewKeyProvider("id"))
	for i := 0; i < 10; i++ {
		foo := fooProvider.NewObject()
		foo.SetValue("id", i)
		foo.SetValue("firsName", fmt.Sprintf("Name %v", i))
		aMap.AddObject(foo)
	}

	//Accessing map
	foo1 := aMap.Object("1")
	JSON, err := json.Marshal(foo1)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", JSON)

	//Iterating map
	err = aMap.Pairs(func(key interface{}, item *gtly.Object) (bool, error) {
		fmt.Printf("id: %v\n", item.Value("id"))
		fmt.Printf("name: %v\n", item.Value("name"))
		return true, nil
	})
	if err != nil {
		log.Fatal(err)
	}

	JSON, err = json.Marshal(aMap)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", JSON)
	//[{"id":1,"firsName":"Name 1","updated":null,"numbers":null},{"id":3,"firsName":"Name 3","updated":null,"numbers":null},{"id":4,"firsName":"Name 4","updated":null,"numbers":null},{"id":6,"firsName":"Name 6","updated":null,"numbers":null},{"id":8,"firsName":"Name 8","updated":null,"numbers":null},{"id":9,"firsName":"Name 9","updated":null,"numbers":null},{"id":0,"firsName":"Name 0","updated":null,"numbers":null},{"id":2,"firsName":"Name 2","updated":null,"numbers":null},{"id":5,"firsName":"Name 5","updated":null,"numbers":null},{"id":7,"firsName":"Name 7","updated":null,"numbers":null}]

}
Output:

func (*Provider) NewMultimap

func (p *Provider) NewMultimap(keyProvider KeyProvider) *Multimap

NewMultimap creates a multimap of string and slice

Example

ExampleProvider_NewMulti new multi example

package main

import (
	"fmt"
	"github.com/viant/gtly"
	"github.com/viant/gtly/codec/json"
	"log"
	"time"
)

func main() {
	fooProvider, err := gtly.NewProvider("foo",
		gtly.NewField("id", gtly.FieldTypeInt),
		gtly.NewField("firsName", gtly.FieldTypeString),
		gtly.NewField("city", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
		gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt(time.RFC3339)),
		gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
	)
	if err != nil {
		log.Fatal(err)
	}

	//Creates a multi map keyed by id Field
	aMap := fooProvider.NewMultimap(gtly.NewKeyProvider("city"))
	for i := 0; i < 10; i++ {
		foo := fooProvider.NewObject()
		foo.SetValue("id", i)
		foo.SetValue("firsName", fmt.Sprintf("Name %v", i))
		if i%2 == 0 {
			foo.SetValue("city", "Cracow")
		} else {
			foo.SetValue("city", "Warsaw")
		}
		aMap.AddObject(foo)
	}

	//Accessing map
	fooInWarsawSlice := aMap.Slice("Warsaw")
	JSON, err := json.Marshal(fooInWarsawSlice)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", JSON)
	//Prints [{"id":1,"firsName":"Name 1","city":"Warsaw","updated":null,"numbers":null},{"id":3,"firsName":"Name 3","city":"Warsaw","updated":null,"numbers":null},{"id":5,"firsName":"Name 5","city":"Warsaw","updated":null,"numbers":null},{"id":7,"firsName":"Name 7","city":"Warsaw","updated":null,"numbers":null},{"id":9,"firsName":"Name 9","city":"Warsaw","updated":null,"numbers":null}]

	//Iterating multi map
	err = aMap.Slices(func(key interface{}, value *gtly.Array) (bool, error) {
		fmt.Printf("%v -> %v\n", key, value.Size())
		return true, nil
	})
	if err != nil {
		log.Fatal(err)
	}

	JSON, err = json.Marshal(aMap)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", JSON)
	//[{"id":0,"firsName":"Name 0","city":"Cracow","updated":null,"numbers":null},{"id":2,"firsName":"Name 2","city":"Cracow","updated":null,"numbers":null},{"id":4,"firsName":"Name 4","city":"Cracow","updated":null,"numbers":null},{"id":6,"firsName":"Name 6","city":"Cracow","updated":null,"numbers":null},{"id":8,"firsName":"Name 8","city":"Cracow","updated":null,"numbers":null},{"id":1,"firsName":"Name 1","city":"Warsaw","updated":null,"numbers":null},{"id":3,"firsName":"Name 3","city":"Warsaw","updated":null,"numbers":null},{"id":5,"firsName":"Name 5","city":"Warsaw","updated":null,"numbers":null},{"id":7,"firsName":"Name 7","city":"Warsaw","updated":null,"numbers":null},{"id":9,"firsName":"Name 9","city":"Warsaw","updated":null,"numbers":null}]

}
Output:

func (*Provider) NewObject

func (p *Provider) NewObject() *Object

NewObject creates an object

Example

ExampleProvider_NewObject new object example

package main

import (
	"fmt"
	"github.com/viant/gtly"
	"github.com/viant/gtly/codec/json"
	"github.com/viant/toolbox/format"
	"log"
	"time"
)

func main() {

	fooProvider, err := gtly.NewProvider("foo",
		gtly.NewField("id", gtly.FieldTypeInt),
		gtly.NewField("firsName", gtly.FieldTypeString),
		gtly.NewField("description", gtly.FieldTypeString, gtly.OmitEmptyOpt(true)),
		gtly.NewField("updated", gtly.FieldTypeTime, gtly.DateLayoutOpt("2006-01-02T15:04:05Z07:00")),
		gtly.NewField("numbers", gtly.FieldTypeArray, gtly.ComponentTypeOpt(gtly.FieldTypeInt)),
	)
	if err != nil {
		log.Fatal(err)
	}
	foo1 := fooProvider.NewObject()
	foo1.SetValue("id", 1)
	foo1.SetValue("firsName", "Adam")
	foo1.SetValue("updated", time.Now())
	foo1.SetValue("numbers", []int{1, 2, 3})

	JSON, err := json.Marshal(foo1)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", JSON)
	fooProvider.OutputCaseFormat(format.CaseLower, format.CaseUpperUnderscore)
	JSON, _ = json.Marshal(foo1)
	fmt.Printf("%s\n", JSON)

	fooProvider.OutputCaseFormat(format.CaseLower, format.CaseLowerUnderscore)
	foo1.SetValue("active", true)
	foo1.SetValue("description", "some description")

	JSON, _ = json.Marshal(foo1)
	fmt.Printf("%s\n", JSON)
}
Output:

func (*Provider) Object

func (p *Provider) Object(value interface{}) (*Object, error)

Object creates an object from struct or map

func (*Provider) UnMarshall added in v0.2.0

func (p *Provider) UnMarshall(data []byte) (*Object, error)

UnMarshall unmarshal objects

type Zeroable

type Zeroable interface {
	IsZero() bool
}

Zeroable represent uninitialise type

Directories

Path Synopsis
codec

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL