From 3617e51c019175a7b17d7de3539a7fdbb4642a74 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 28 Sep 2020 23:52:02 +0800 Subject: [PATCH] improve gdb.Model.ScanList --- database/gdb/gdb_type_result_scanlist.go | 36 ++++++++++++++++++------ go.mod | 1 + util/gconv/gconv_struct.go | 6 ++-- util/gconv/gconv_structs.go | 3 +- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/database/gdb/gdb_type_result_scanlist.go b/database/gdb/gdb_type_result_scanlist.go index 3b4a41648..9db4565db 100644 --- a/database/gdb/gdb_type_result_scanlist.go +++ b/database/gdb/gdb_type_result_scanlist.go @@ -181,7 +181,7 @@ func (r Result) ScanList(listPointer interface{}, attributeName string, relation } } if len(relationDataMap) > 0 && !relationValue.IsValid() { - return fmt.Errorf(`invalid relation: %s, %s`, relation[0], relation[1]) + return fmt.Errorf(`invalid relation: "%s:%s"`, relation[0], relation[1]) } switch attrKind { case reflect.Array, reflect.Slice: @@ -196,7 +196,7 @@ func (r Result) ScanList(listPointer interface{}, attributeName string, relation } } else { // May be the attribute does not exist yet. - return fmt.Errorf(`invalid relation: %s, %s`, relation[0], relation[1]) + return fmt.Errorf(`invalid relation: "%s:%s"`, relation[0], relation[1]) } } else { return fmt.Errorf(`relationKey should not be empty as field "%s" is slice`, attributeName) @@ -207,15 +207,25 @@ func (r Result) ScanList(listPointer interface{}, attributeName string, relation if len(relationDataMap) > 0 { relationField = relationValue.FieldByName(relationAttrName) if relationField.IsValid() { - if err = gconv.Struct(relationDataMap[gconv.String(relationField.Interface())], e); err != nil { + v := relationDataMap[gconv.String(relationField.Interface())] + if v == nil { + // There's no relational data. + continue + } + if err = gconv.Struct(v, e); err != nil { return err } } else { // May be the attribute does not exist yet. - return fmt.Errorf(`invalid relation: %s, %s`, relation[0], relation[1]) + return fmt.Errorf(`invalid relation: "%s:%s"`, relation[0], relation[1]) } } else { - if err = gconv.Struct(r[i], e); err != nil { + v := r[i] + if v == nil { + // There's no relational data. + continue + } + if err = gconv.Struct(v, e); err != nil { return err } } @@ -226,15 +236,25 @@ func (r Result) ScanList(listPointer interface{}, attributeName string, relation if len(relationDataMap) > 0 { relationField = relationValue.FieldByName(relationAttrName) if relationField.IsValid() { - if err = gconv.Struct(relationDataMap[gconv.String(relationField.Interface())], e); err != nil { + v := relationDataMap[gconv.String(relationField.Interface())] + if v == nil { + // There's no relational data. + continue + } + if err = gconv.Struct(v, e); err != nil { return err } } else { // May be the attribute does not exist yet. - return fmt.Errorf(`invalid relation: %s, %s`, relation[0], relation[1]) + return fmt.Errorf(`invalid relation: "%s:%s"`, relation[0], relation[1]) } } else { - if err = gconv.Struct(r[i], e); err != nil { + v := r[i] + if v == nil { + // There's no relational data. + continue + } + if err = gconv.Struct(v, e); err != nil { return err } } diff --git a/go.mod b/go.mod index 385d6c370..56d7cae7a 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/gqcn/structs v1.1.1 github.com/grokify/html-strip-tags-go v0.0.0-20190921062105-daaa06bf1aaf github.com/json-iterator/go v1.1.10 + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/olekukonko/tablewriter v0.0.1 golang.org/x/net v0.0.0-20200602114024-627f9648deb9 golang.org/x/text v0.3.2 diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index 44e9cf5c6..26cd0de03 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -50,7 +50,8 @@ func StructDeep(params interface{}, pointer interface{}, mapping ...map[string]s // doStruct is the core internal converting function for any data to struct recursively or not. func doStruct(params interface{}, pointer interface{}, recursive bool, mapping ...map[string]string) (err error) { if params == nil { - return gerror.New("params cannot be nil") + // If is nil, no conversion. + return nil } if pointer == nil { return gerror.New("object pointer cannot be nil") @@ -73,7 +74,8 @@ func doStruct(params interface{}, pointer interface{}, recursive bool, mapping . // DO NOT use MapDeep here. paramsMap := Map(params) if paramsMap == nil { - return gerror.Newf("invalid params: %v", params) + //return gerror.Newf("invalid params: %v", params) + return nil } // Using reflect to do the converting, diff --git a/util/gconv/gconv_structs.go b/util/gconv/gconv_structs.go index f447fcf6f..1885acc49 100644 --- a/util/gconv/gconv_structs.go +++ b/util/gconv/gconv_structs.go @@ -30,7 +30,8 @@ func StructsDeep(params interface{}, pointer interface{}, mapping ...map[string] // it will create the struct/pointer internally. func doStructs(params interface{}, pointer interface{}, deep bool, mapping ...map[string]string) (err error) { if params == nil { - return gerror.New("params cannot be nil") + // If is nil, no conversion. + return nil } if pointer == nil { return gerror.New("object pointer cannot be nil")