You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
I'm looking to see if there's a tag available to skip a field if that field value is nil.
My use case: I use "request" types to limit the scope of what can be modified in a data set. I heavily use this style around updating, which allows you to skip the update of a value/column if it's nil, but update the value if it's a real value including an empty string (ex. user wants to remove their phone number)
// standard type, no pointersUserCreateRequeststruct {
Namestring`db:"name" validate:"required"`Emailstring`db:"email" validate:"required"`Passwordstring`db:"password" validate:"required"`Ageint`db:"age"`Phonestring`db:"phone"`
}
// pointer types to allow updating of only real values. Empty string "" or 0 for example is considered a real value.UserUpdateRequeststruct {
Name*string`db:"name"`Age*int`db:"age"`Phone*string`db:"phone"`
}
// Example request struct// struct is typically filled in the unmarshalling process, but for example purposes I have it more explicitur:=&UserUpdateRequest{}
phone:=""ur.Phone=phonestmt, args, _:=db.Update("tests").Set(ur).Where(goqu.Ex{"id":1}).Prepared(true).ToSql()
// Output:// stmt: UPDATE "tests" SET "phone"=$1 WHERE ("id" = $2)// args: []interface{"",1}
Describe the solution you'd like
maybe a new tag that checks for and skips nil values? ie. db:"skipIfNil"
I've loosely implemented this already with the below code, but it has some limitations. You may be able to include it more seamlessly with the functionality you already have.
// flattenStruct takes in a struct and will reduce it to a map.// If the type is a pointer and it is nil or if has an ignore tag "-", the key/value pair will not be added to the map.// it's best to use pointer types on update request structs since only real values will remain in final map.funcflattenStruct(iinterface{}) interface{} {
v:=reflect.ValueOf(i)
ifv.Kind() ==reflect.Interface {
v=v.Elem()
}
ifv.Kind() ==reflect.Ptr {
v=v.Elem()
}
switchv.Kind() {
casereflect.Map:
returnicasereflect.Struct:
m:=make(map[string]interface{})
mapRecursion(v, "", m)
returnmcasereflect.Slice:
mm:=make([]map[string]interface{}, v.Len())
fori:=0; i<v.Len(); i++ {
vv:=v.Index(i)
m:=make(map[string]interface{})
mapRecursion(vv, "", m)
mm[i] =m
}
returnmm
}
returnmap[string]interface{}{}
}
funcmapRecursion(v reflect.Value, mapKeystring, mmap[string]interface{}) {
switchv.Kind() {
casereflect.Interface:
if!v.IsNil() {
mapRecursion(v.Elem(), mapKey, m)
}
casereflect.Ptr:
if!v.IsNil() {
mapRecursion(v.Elem(), mapKey, m)
}
casereflect.Struct:
switcht:=v.Interface().(type) {
case time.Time:
if!t.IsZero() {
m[strings.CamelCase(mapKey)] =v.Interface()
}
case driver.Valuer:
m[strings.CamelCase(mapKey)] =v.Interface()
default:
fori:=0; i<v.NumField(); i++ {
val:=v.Field(i)
tf:=v.Type().Field(i)
q:=tf.Tag.Get("db")
ifq=="-" {
continue
}
mapRecursion(val, tf.Name, m)
}
}
casereflect.Map:
iter:=v.MapRange()
foriter.Next() {
k:=iter.Key()
v:=iter.Value()
mapRecursion(v, k.String(), m)
}
casereflect.Slice:
if!v.CanInterface() {
return
}
switcht:=v.Interface().(type) {
case []int:
ii:=make(pq.Int64Array, v.Len())
fori:=0; i<v.Len(); i++ {
ii[i] =int64(t[i])
}
mapRecursion(reflect.ValueOf(ii), mapKey, m)
case []int64:
mapRecursion(reflect.ValueOf(pq.Int64Array(t)), mapKey, m)
case []float64:
mapRecursion(reflect.ValueOf(pq.Float64Array(t)), mapKey, m)
case []string:
mapRecursion(reflect.ValueOf(pq.StringArray(t)), mapKey, m)
case []bool:
mapRecursion(reflect.ValueOf(pq.BoolArray(t)), mapKey, m)
case pq.Int64Array, pq.StringArray, pq.BoolArray, pq.Float64Array:
m[strings.CamelCase(mapKey)] =t
}
default:
ifv.CanInterface() &&mapKey!="" {
m[strings.CamelCase(mapKey)] =v.Interface()
}
}
}
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem? Please describe.
I'm looking to see if there's a tag available to skip a field if that field value is nil.
My use case: I use "request" types to limit the scope of what can be modified in a data set. I heavily use this style around updating, which allows you to skip the update of a value/column if it's nil, but update the value if it's a real value including an empty string (ex. user wants to remove their phone number)
Describe the solution you'd like
maybe a new tag that checks for and skips nil values? ie.
db:"skipIfNil"
Describe alternatives you've considered
I saw this already, but doesn't address the request as far as I can tell.
https://godoc.org/github.com/doug-martin/goqu#example-UpdateDataset-Set-WithNilEmbeddedPointer
Dialect
I've loosely implemented this already with the below code, but it has some limitations. You may be able to include it more seamlessly with the functionality you already have.
The text was updated successfully, but these errors were encountered: