Improve expr types, add r/w locking
This commit is contained in:
Generated
+271
-105
@@ -12,6 +12,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -19,7 +20,10 @@ var _ = context.Background
|
||||
var _ = fmt.Errorf
|
||||
|
||||
// Any is an expression type, wrapper for interface{} type
|
||||
type Any struct{ value interface{} }
|
||||
type Any struct {
|
||||
value interface{}
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewAny creates new instance of Any expression type
|
||||
func NewAny(val interface{}) (*Any, error) {
|
||||
@@ -30,16 +34,24 @@ func NewAny(val interface{}) (*Any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Any
|
||||
func (t Any) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Any
|
||||
func (t *Any) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Any
|
||||
func (t Any) GetValue() interface{} { return t.value }
|
||||
// GetValue returns underlying value on Any
|
||||
func (t *Any) GetValue() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Any) Type() string { return "Any" }
|
||||
|
||||
// Convert value to interface{}
|
||||
// Cast converts value to interface{}
|
||||
func (Any) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewAny(val)
|
||||
}
|
||||
@@ -57,7 +69,10 @@ func (t *Any) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Array is an expression type, wrapper for []TypedValue type
|
||||
type Array struct{ value []TypedValue }
|
||||
type Array struct {
|
||||
value []TypedValue
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewArray creates new instance of Array expression type
|
||||
func NewArray(val interface{}) (*Array, error) {
|
||||
@@ -68,16 +83,24 @@ func NewArray(val interface{}) (*Array, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Array
|
||||
func (t Array) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Array
|
||||
func (t *Array) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Array
|
||||
func (t Array) GetValue() []TypedValue { return t.value }
|
||||
// GetValue returns underlying value on Array
|
||||
func (t *Array) GetValue() []TypedValue {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Array) Type() string { return "Array" }
|
||||
|
||||
// Convert value to []TypedValue
|
||||
// Cast converts value to []TypedValue
|
||||
func (Array) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewArray(val)
|
||||
}
|
||||
@@ -95,7 +118,10 @@ func (t *Array) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Boolean is an expression type, wrapper for bool type
|
||||
type Boolean struct{ value bool }
|
||||
type Boolean struct {
|
||||
value bool
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewBoolean creates new instance of Boolean expression type
|
||||
func NewBoolean(val interface{}) (*Boolean, error) {
|
||||
@@ -106,16 +132,24 @@ func NewBoolean(val interface{}) (*Boolean, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Boolean
|
||||
func (t Boolean) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Boolean
|
||||
func (t *Boolean) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Boolean
|
||||
func (t Boolean) GetValue() bool { return t.value }
|
||||
// GetValue returns underlying value on Boolean
|
||||
func (t *Boolean) GetValue() bool {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Boolean) Type() string { return "Boolean" }
|
||||
|
||||
// Convert value to bool
|
||||
// Cast converts value to bool
|
||||
func (Boolean) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewBoolean(val)
|
||||
}
|
||||
@@ -133,7 +167,10 @@ func (t *Boolean) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// DateTime is an expression type, wrapper for *time.Time type
|
||||
type DateTime struct{ value *time.Time }
|
||||
type DateTime struct {
|
||||
value *time.Time
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewDateTime creates new instance of DateTime expression type
|
||||
func NewDateTime(val interface{}) (*DateTime, error) {
|
||||
@@ -144,16 +181,24 @@ func NewDateTime(val interface{}) (*DateTime, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on DateTime
|
||||
func (t DateTime) Get() interface{} { return t.value }
|
||||
// Get return underlying value on DateTime
|
||||
func (t *DateTime) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on DateTime
|
||||
func (t DateTime) GetValue() *time.Time { return t.value }
|
||||
// GetValue returns underlying value on DateTime
|
||||
func (t *DateTime) GetValue() *time.Time {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (DateTime) Type() string { return "DateTime" }
|
||||
|
||||
// Convert value to *time.Time
|
||||
// Cast converts value to *time.Time
|
||||
func (DateTime) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewDateTime(val)
|
||||
}
|
||||
@@ -171,7 +216,10 @@ func (t *DateTime) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Duration is an expression type, wrapper for time.Duration type
|
||||
type Duration struct{ value time.Duration }
|
||||
type Duration struct {
|
||||
value time.Duration
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewDuration creates new instance of Duration expression type
|
||||
func NewDuration(val interface{}) (*Duration, error) {
|
||||
@@ -182,16 +230,24 @@ func NewDuration(val interface{}) (*Duration, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Duration
|
||||
func (t Duration) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Duration
|
||||
func (t *Duration) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Duration
|
||||
func (t Duration) GetValue() time.Duration { return t.value }
|
||||
// GetValue returns underlying value on Duration
|
||||
func (t *Duration) GetValue() time.Duration {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Duration) Type() string { return "Duration" }
|
||||
|
||||
// Convert value to time.Duration
|
||||
// Cast converts value to time.Duration
|
||||
func (Duration) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewDuration(val)
|
||||
}
|
||||
@@ -209,7 +265,10 @@ func (t *Duration) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Float is an expression type, wrapper for float64 type
|
||||
type Float struct{ value float64 }
|
||||
type Float struct {
|
||||
value float64
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewFloat creates new instance of Float expression type
|
||||
func NewFloat(val interface{}) (*Float, error) {
|
||||
@@ -220,16 +279,24 @@ func NewFloat(val interface{}) (*Float, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Float
|
||||
func (t Float) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Float
|
||||
func (t *Float) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Float
|
||||
func (t Float) GetValue() float64 { return t.value }
|
||||
// GetValue returns underlying value on Float
|
||||
func (t *Float) GetValue() float64 {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Float) Type() string { return "Float" }
|
||||
|
||||
// Convert value to float64
|
||||
// Cast converts value to float64
|
||||
func (Float) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewFloat(val)
|
||||
}
|
||||
@@ -247,7 +314,10 @@ func (t *Float) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Handle is an expression type, wrapper for string type
|
||||
type Handle struct{ value string }
|
||||
type Handle struct {
|
||||
value string
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewHandle creates new instance of Handle expression type
|
||||
func NewHandle(val interface{}) (*Handle, error) {
|
||||
@@ -258,16 +328,24 @@ func NewHandle(val interface{}) (*Handle, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Handle
|
||||
func (t Handle) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Handle
|
||||
func (t *Handle) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Handle
|
||||
func (t Handle) GetValue() string { return t.value }
|
||||
// GetValue returns underlying value on Handle
|
||||
func (t *Handle) GetValue() string {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Handle) Type() string { return "Handle" }
|
||||
|
||||
// Convert value to string
|
||||
// Cast converts value to string
|
||||
func (Handle) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewHandle(val)
|
||||
}
|
||||
@@ -285,7 +363,10 @@ func (t *Handle) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// ID is an expression type, wrapper for uint64 type
|
||||
type ID struct{ value uint64 }
|
||||
type ID struct {
|
||||
value uint64
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewID creates new instance of ID expression type
|
||||
func NewID(val interface{}) (*ID, error) {
|
||||
@@ -296,16 +377,24 @@ func NewID(val interface{}) (*ID, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on ID
|
||||
func (t ID) Get() interface{} { return t.value }
|
||||
// Get return underlying value on ID
|
||||
func (t *ID) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on ID
|
||||
func (t ID) GetValue() uint64 { return t.value }
|
||||
// GetValue returns underlying value on ID
|
||||
func (t *ID) GetValue() uint64 {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (ID) Type() string { return "ID" }
|
||||
|
||||
// Convert value to uint64
|
||||
// Cast converts value to uint64
|
||||
func (ID) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewID(val)
|
||||
}
|
||||
@@ -323,7 +412,10 @@ func (t *ID) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Integer is an expression type, wrapper for int64 type
|
||||
type Integer struct{ value int64 }
|
||||
type Integer struct {
|
||||
value int64
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewInteger creates new instance of Integer expression type
|
||||
func NewInteger(val interface{}) (*Integer, error) {
|
||||
@@ -334,16 +426,24 @@ func NewInteger(val interface{}) (*Integer, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Integer
|
||||
func (t Integer) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Integer
|
||||
func (t *Integer) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Integer
|
||||
func (t Integer) GetValue() int64 { return t.value }
|
||||
// GetValue returns underlying value on Integer
|
||||
func (t *Integer) GetValue() int64 {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Integer) Type() string { return "Integer" }
|
||||
|
||||
// Convert value to int64
|
||||
// Cast converts value to int64
|
||||
func (Integer) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewInteger(val)
|
||||
}
|
||||
@@ -361,7 +461,10 @@ func (t *Integer) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// KV is an expression type, wrapper for map[string]string type
|
||||
type KV struct{ value map[string]string }
|
||||
type KV struct {
|
||||
value map[string]string
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewKV creates new instance of KV expression type
|
||||
func NewKV(val interface{}) (*KV, error) {
|
||||
@@ -372,16 +475,24 @@ func NewKV(val interface{}) (*KV, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on KV
|
||||
func (t KV) Get() interface{} { return t.value }
|
||||
// Get return underlying value on KV
|
||||
func (t *KV) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on KV
|
||||
func (t KV) GetValue() map[string]string { return t.value }
|
||||
// GetValue returns underlying value on KV
|
||||
func (t *KV) GetValue() map[string]string {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (KV) Type() string { return "KV" }
|
||||
|
||||
// Convert value to map[string]string
|
||||
// Cast converts value to map[string]string
|
||||
func (KV) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewKV(val)
|
||||
}
|
||||
@@ -399,7 +510,10 @@ func (t *KV) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// KVV is an expression type, wrapper for map[string][]string type
|
||||
type KVV struct{ value map[string][]string }
|
||||
type KVV struct {
|
||||
value map[string][]string
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewKVV creates new instance of KVV expression type
|
||||
func NewKVV(val interface{}) (*KVV, error) {
|
||||
@@ -410,16 +524,24 @@ func NewKVV(val interface{}) (*KVV, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on KVV
|
||||
func (t KVV) Get() interface{} { return t.value }
|
||||
// Get return underlying value on KVV
|
||||
func (t *KVV) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on KVV
|
||||
func (t KVV) GetValue() map[string][]string { return t.value }
|
||||
// GetValue returns underlying value on KVV
|
||||
func (t *KVV) GetValue() map[string][]string {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (KVV) Type() string { return "KVV" }
|
||||
|
||||
// Convert value to map[string][]string
|
||||
// Cast converts value to map[string][]string
|
||||
func (KVV) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewKVV(val)
|
||||
}
|
||||
@@ -437,7 +559,10 @@ func (t *KVV) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Reader is an expression type, wrapper for io.Reader type
|
||||
type Reader struct{ value io.Reader }
|
||||
type Reader struct {
|
||||
value io.Reader
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewReader creates new instance of Reader expression type
|
||||
func NewReader(val interface{}) (*Reader, error) {
|
||||
@@ -448,16 +573,24 @@ func NewReader(val interface{}) (*Reader, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Reader
|
||||
func (t Reader) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Reader
|
||||
func (t *Reader) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Reader
|
||||
func (t Reader) GetValue() io.Reader { return t.value }
|
||||
// GetValue returns underlying value on Reader
|
||||
func (t *Reader) GetValue() io.Reader {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Reader) Type() string { return "Reader" }
|
||||
|
||||
// Convert value to io.Reader
|
||||
// Cast converts value to io.Reader
|
||||
func (Reader) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewReader(val)
|
||||
}
|
||||
@@ -475,7 +608,10 @@ func (t *Reader) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// String is an expression type, wrapper for string type
|
||||
type String struct{ value string }
|
||||
type String struct {
|
||||
value string
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewString creates new instance of String expression type
|
||||
func NewString(val interface{}) (*String, error) {
|
||||
@@ -486,16 +622,24 @@ func NewString(val interface{}) (*String, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on String
|
||||
func (t String) Get() interface{} { return t.value }
|
||||
// Get return underlying value on String
|
||||
func (t *String) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on String
|
||||
func (t String) GetValue() string { return t.value }
|
||||
// GetValue returns underlying value on String
|
||||
func (t *String) GetValue() string {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (String) Type() string { return "String" }
|
||||
|
||||
// Convert value to string
|
||||
// Cast converts value to string
|
||||
func (String) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewString(val)
|
||||
}
|
||||
@@ -513,7 +657,10 @@ func (t *String) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// UnsignedInteger is an expression type, wrapper for uint64 type
|
||||
type UnsignedInteger struct{ value uint64 }
|
||||
type UnsignedInteger struct {
|
||||
value uint64
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewUnsignedInteger creates new instance of UnsignedInteger expression type
|
||||
func NewUnsignedInteger(val interface{}) (*UnsignedInteger, error) {
|
||||
@@ -524,16 +671,24 @@ func NewUnsignedInteger(val interface{}) (*UnsignedInteger, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on UnsignedInteger
|
||||
func (t UnsignedInteger) Get() interface{} { return t.value }
|
||||
// Get return underlying value on UnsignedInteger
|
||||
func (t *UnsignedInteger) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on UnsignedInteger
|
||||
func (t UnsignedInteger) GetValue() uint64 { return t.value }
|
||||
// GetValue returns underlying value on UnsignedInteger
|
||||
func (t *UnsignedInteger) GetValue() uint64 {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (UnsignedInteger) Type() string { return "UnsignedInteger" }
|
||||
|
||||
// Convert value to uint64
|
||||
// Cast converts value to uint64
|
||||
func (UnsignedInteger) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewUnsignedInteger(val)
|
||||
}
|
||||
@@ -551,7 +706,10 @@ func (t *UnsignedInteger) Assign(val interface{}) error {
|
||||
}
|
||||
|
||||
// Vars is an expression type, wrapper for map[string]TypedValue type
|
||||
type Vars struct{ value map[string]TypedValue }
|
||||
type Vars struct {
|
||||
value map[string]TypedValue
|
||||
mux sync.RWMutex
|
||||
}
|
||||
|
||||
// NewVars creates new instance of Vars expression type
|
||||
func NewVars(val interface{}) (*Vars, error) {
|
||||
@@ -562,16 +720,24 @@ func NewVars(val interface{}) (*Vars, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return underlying value on Vars
|
||||
func (t Vars) Get() interface{} { return t.value }
|
||||
// Get return underlying value on Vars
|
||||
func (t *Vars) Get() interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return underlying value on Vars
|
||||
func (t Vars) GetValue() map[string]TypedValue { return t.value }
|
||||
// GetValue returns underlying value on Vars
|
||||
func (t *Vars) GetValue() map[string]TypedValue {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
return t.value
|
||||
}
|
||||
|
||||
// Return type name
|
||||
// Type return type name
|
||||
func (Vars) Type() string { return "Vars" }
|
||||
|
||||
// Convert value to map[string]TypedValue
|
||||
// Cast converts value to map[string]TypedValue
|
||||
func (Vars) Cast(val interface{}) (TypedValue, error) {
|
||||
return NewVars(val)
|
||||
}
|
||||
|
||||
@@ -137,10 +137,10 @@ func Typify(in interface{}) (tv TypedValue, err error) {
|
||||
if v, err := CastToVars(c); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Vars{v}, nil
|
||||
return &Vars{value: v}, nil
|
||||
}
|
||||
case map[string]TypedValue:
|
||||
return &Vars{c}, nil
|
||||
return &Vars{value: c}, nil
|
||||
case map[string]string:
|
||||
return &KV{value: c}, nil
|
||||
case map[string][]string:
|
||||
|
||||
+28
-27
@@ -3,10 +3,11 @@ package expr
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/require"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Example_set_kv() {
|
||||
@@ -20,11 +21,11 @@ func Example_set_kv() {
|
||||
)
|
||||
|
||||
eval(`set(kv, key, value)`, p)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k1:v11]}
|
||||
// Original KV should be &{map[]}
|
||||
// map[k1:v11]
|
||||
// Original KV should be map[]
|
||||
}
|
||||
|
||||
func Example_merge_kv() {
|
||||
@@ -42,11 +43,11 @@ func Example_merge_kv() {
|
||||
)
|
||||
|
||||
eval(`merge(kv, foo, bar)`, p)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k1:v1 k2:v2]}
|
||||
// Original KV should be &{map[]}
|
||||
// map[k1:v1 k2:v2]
|
||||
// Original KV should be map[]
|
||||
}
|
||||
|
||||
func Example_filter_kv() {
|
||||
@@ -63,11 +64,11 @@ func Example_filter_kv() {
|
||||
)
|
||||
|
||||
eval(`filter(kv, key1, key2)`, p)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k1:v1]}
|
||||
// Original KV should be &{map[k1:v1 k2:v2]}
|
||||
// map[k1:v1]
|
||||
// Original KV should be map[k1:v1 k2:v2]
|
||||
}
|
||||
|
||||
func Example_omit_kv() {
|
||||
@@ -85,11 +86,11 @@ func Example_omit_kv() {
|
||||
)
|
||||
|
||||
eval(`omit(kv, key1, key2)`, p)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv)
|
||||
fmt.Printf("\nOriginal KV should be %v", kv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k2:v2]}
|
||||
// Original KV should be &{map[k1:v1 k2:v2 k3:v3]}
|
||||
// map[k2:v2]
|
||||
// Original KV should be map[k1:v1 k2:v2 k3:v3]
|
||||
}
|
||||
|
||||
func Example_set_kvv() {
|
||||
@@ -103,11 +104,11 @@ func Example_set_kvv() {
|
||||
)
|
||||
|
||||
eval(`set(kvv, key, value)`, p)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[foo:[bar]]}
|
||||
// Original KVV should be &{map[]}
|
||||
// map[foo:[bar]]
|
||||
// Original KVV should be map[]
|
||||
}
|
||||
|
||||
func Example_merge_kvv() {
|
||||
@@ -126,11 +127,11 @@ func Example_merge_kvv() {
|
||||
)
|
||||
|
||||
eval(`merge(kvv, foo, bar)`, p)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k1:[v1 v11] k2:[v2]]}
|
||||
// Original KVV should be &{map[]}
|
||||
// map[k1:[v1 v11] k2:[v2]]
|
||||
// Original KVV should be map[]
|
||||
}
|
||||
|
||||
func Example_filter_kvv() {
|
||||
@@ -147,11 +148,11 @@ func Example_filter_kvv() {
|
||||
)
|
||||
|
||||
eval(`filter(kv, key1, key2)`, p)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k1:[v1]]}
|
||||
// Original KVV should be &{map[k1:[v1] k2:[v2]]}
|
||||
// map[k1:[v1]]
|
||||
// Original KVV should be map[k1:[v1] k2:[v2]]
|
||||
}
|
||||
|
||||
func Example_omit_kvv() {
|
||||
@@ -169,11 +170,11 @@ func Example_omit_kvv() {
|
||||
)
|
||||
|
||||
eval(`omit(kvv, key1, key2)`, p)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv)
|
||||
fmt.Printf("\nOriginal KVV should be %v", kvv.value)
|
||||
|
||||
// output:
|
||||
// &{value:map[k2:[v2]]}
|
||||
// Original KVV should be &{map[k1:[v1] k2:[v2] k3:[v3]]}
|
||||
// map[k2:[v2]]
|
||||
// Original KVV should be map[k1:[v1] k2:[v2] k3:[v3]]
|
||||
}
|
||||
|
||||
func TestTypedValueOperations(t *testing.T) {
|
||||
@@ -527,10 +528,10 @@ func TestArrayDecode(t *testing.T) {
|
||||
req.NoError(err)
|
||||
|
||||
vars, err := NewVars(map[string]interface{}{
|
||||
"strings": &Array{arr},
|
||||
"strings": &Array{value: arr},
|
||||
"iface": Must(NewString("typed")),
|
||||
"typed": Must(NewString("typed")),
|
||||
"values": &Array{arr},
|
||||
"values": &Array{value: arr},
|
||||
})
|
||||
|
||||
req.NoError(err)
|
||||
|
||||
+1
-1
@@ -103,6 +103,6 @@ func eval(e string, p interface{}) {
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v", err)
|
||||
} else {
|
||||
fmt.Printf("%+v", result)
|
||||
fmt.Printf("%+v", UntypedValue(result))
|
||||
}
|
||||
}
|
||||
|
||||
+83
-20
@@ -13,11 +13,17 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
func (t Vars) Len() int {
|
||||
func (t *Vars) Len() int {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
return len(t.value)
|
||||
}
|
||||
|
||||
func (t Vars) Select(k string) (TypedValue, error) {
|
||||
func (t *Vars) Select(k string) (TypedValue, error) {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if v, is := t.value[k]; is {
|
||||
return v, nil
|
||||
} else {
|
||||
@@ -26,6 +32,9 @@ func (t Vars) Select(k string) (TypedValue, error) {
|
||||
}
|
||||
|
||||
func (t *Vars) AssignFieldValue(key string, val TypedValue) (err error) {
|
||||
t.mux.Lock()
|
||||
defer t.mux.Unlock()
|
||||
|
||||
if t.value == nil {
|
||||
t.value = make(map[string]TypedValue)
|
||||
}
|
||||
@@ -35,7 +44,14 @@ func (t *Vars) AssignFieldValue(key string, val TypedValue) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (t Vars) ResolveTypes(res func(typ string) Type) (err error) {
|
||||
func (t *Vars) ResolveTypes(res func(typ string) Type) (err error) {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
for k, v := range t.value {
|
||||
if u, is := v.(*Unresolved); is {
|
||||
if res(u.Type()) == nil {
|
||||
@@ -61,28 +77,22 @@ func (t Vars) ResolveTypes(res func(typ string) Type) (err error) {
|
||||
// Merge combines the given Vars(es) into Vars
|
||||
// NOTE: It will return CLONE of the original Vars, if its called without any parameters
|
||||
func (t *Vars) Merge(nn ...Iterator) (out TypedValue, err error) {
|
||||
vars := EmptyVars()
|
||||
|
||||
nn = append([]Iterator{t}, nn...)
|
||||
|
||||
for _, i := range nn {
|
||||
_ = i.Each(func(k string, v TypedValue) error {
|
||||
vars.value[k] = v
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
return vars, nil
|
||||
return t.MustMerge(nn...), nil
|
||||
}
|
||||
|
||||
// MustMerge returns Vars after merging the given Vars(es) into it
|
||||
func (t *Vars) MustMerge(nn ...Iterator) *Vars {
|
||||
if t != nil {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
nn = append([]Iterator{t}, nn...)
|
||||
}
|
||||
|
||||
var (
|
||||
out = &Vars{value: make(map[string]TypedValue)}
|
||||
)
|
||||
|
||||
nn = append([]Iterator{t}, nn...)
|
||||
|
||||
for _, i := range nn {
|
||||
_ = i.Each(func(k string, v TypedValue) error {
|
||||
out.value[k] = v
|
||||
@@ -99,6 +109,13 @@ func (t *Vars) Copy(dst *Vars, kk ...string) {
|
||||
return
|
||||
}
|
||||
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if dst.value == nil {
|
||||
dst.value = make(map[string]TypedValue)
|
||||
}
|
||||
@@ -119,6 +136,13 @@ func (t *Vars) HasAll(key string, kk ...string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, key = range append([]string{key}, kk...) {
|
||||
if _, has := t.value[key]; !has {
|
||||
return false
|
||||
@@ -146,6 +170,9 @@ func (t *Vars) HasAny(key string, kk ...string) bool {
|
||||
var _ gval.Selector = &Vars{}
|
||||
|
||||
func (t *Vars) Dict() map[string]interface{} {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
dict := make(map[string]interface{})
|
||||
for k, v := range t.value {
|
||||
switch v := v.(type) {
|
||||
@@ -177,6 +204,9 @@ func (t *Vars) Decode(dst interface{}) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
dstRef := reflect.ValueOf(dst)
|
||||
|
||||
if dstRef.Kind() != reflect.Ptr {
|
||||
@@ -234,10 +264,18 @@ func (t *Vars) Scan(value interface{}) error {
|
||||
}
|
||||
|
||||
func (t *Vars) Value() (driver.Value, error) {
|
||||
if t != nil {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
}
|
||||
|
||||
return json.Marshal(t)
|
||||
}
|
||||
|
||||
func (t Vars) SelectGVal(_ context.Context, k string) (interface{}, error) {
|
||||
func (t *Vars) SelectGVal(_ context.Context, k string) (interface{}, error) {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
val, err := t.Select(k)
|
||||
switch c := val.(type) {
|
||||
case gval.Selector:
|
||||
@@ -249,6 +287,9 @@ func (t Vars) SelectGVal(_ context.Context, k string) (interface{}, error) {
|
||||
|
||||
// UnmarshalJSON unmarshal JSON value into Vars
|
||||
func (t *Vars) UnmarshalJSON(in []byte) (err error) {
|
||||
t.mux.Lock()
|
||||
defer t.mux.Unlock()
|
||||
|
||||
var (
|
||||
aux = make(map[string]*typedValueWrap)
|
||||
)
|
||||
@@ -275,7 +316,14 @@ func (t *Vars) UnmarshalJSON(in []byte) (err error) {
|
||||
}
|
||||
|
||||
func (t *Vars) Each(fn func(k string, v TypedValue) error) (err error) {
|
||||
if t == nil || t.value == nil {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if t.value == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -290,6 +338,9 @@ func (t *Vars) Each(fn func(k string, v TypedValue) error) (err error) {
|
||||
|
||||
// Set set/update the specific key value in KV
|
||||
func (t *Vars) Set(k string, v interface{}) (err error) {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if t.value == nil {
|
||||
t.value = make(map[string]TypedValue)
|
||||
}
|
||||
@@ -299,7 +350,10 @@ func (t *Vars) Set(k string, v interface{}) (err error) {
|
||||
}
|
||||
|
||||
// MarshalJSON returns JSON encoding of expression
|
||||
func (t Vars) MarshalJSON() ([]byte, error) {
|
||||
func (t *Vars) MarshalJSON() ([]byte, error) {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
aux := make(map[string]*typedValueWrap)
|
||||
for k, v := range t.value {
|
||||
if v == nil {
|
||||
@@ -410,6 +464,9 @@ func CastToVars(val interface{}) (out map[string]TypedValue, err error) {
|
||||
|
||||
switch c := val.(type) {
|
||||
case *Vars:
|
||||
c.mux.RLock()
|
||||
defer c.mux.RUnlock()
|
||||
|
||||
return c.value, nil
|
||||
case map[string]TypedValue:
|
||||
return c, nil
|
||||
@@ -430,6 +487,9 @@ func CastToVars(val interface{}) (out map[string]TypedValue, err error) {
|
||||
|
||||
// Filter take keys returns KV with only those key value pair
|
||||
func (t *Vars) Filter(keys ...string) (out TypedValue, err error) {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if t.value == nil {
|
||||
return
|
||||
}
|
||||
@@ -447,6 +507,9 @@ func (t *Vars) Filter(keys ...string) (out TypedValue, err error) {
|
||||
|
||||
// Delete take keys returns KV without those key value pair
|
||||
func (t *Vars) Delete(keys ...string) (out TypedValue, err error) {
|
||||
t.mux.RLock()
|
||||
defer t.mux.RUnlock()
|
||||
|
||||
if t.value == nil {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user