github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/dac/specifications/argument.go (about) 1 package specifications 2 3 import ( 4 "github.com/aacfactory/errors" 5 "github.com/aacfactory/json" 6 "reflect" 7 ) 8 9 func (spec *Specification) Arguments(instance any, fieldNames []string) (arguments []any, err error) { 10 rv := reflect.Indirect(reflect.ValueOf(instance)) 11 for _, fieldName := range fieldNames { 12 var target *Column 13 for _, column := range spec.Columns { 14 if column.Field == fieldName { 15 target = column 16 break 17 } 18 } 19 if target == nil { 20 err = errors.Warning("sql: field was not found").WithMeta("table", rv.Type().String()) 21 return 22 } 23 switch target.Kind { 24 case Normal, Pk, Acb, Act, Amb, Amt, Adb, Adt, Aol: 25 fv := target.ReadValue(rv) 26 arguments = append(arguments, fv.Interface()) 27 break 28 case Reference: 29 fv := target.ReadValue(rv) 30 if fv.Type().Kind() == reflect.Ptr { 31 if fv.IsNil() { 32 arguments = append(arguments, nil) 33 break 34 } 35 fv = fv.Elem() 36 } 37 refField, mapping, ok := target.Reference() 38 if !ok { 39 err = errors.Warning("sql: field is not reference").WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 40 return 41 } 42 ref := fv.Interface() 43 argument, argumentErr := mapping.ArgumentByField(ref, refField) 44 if argumentErr != nil { 45 err = errors.Warning("sql: get field value failed").WithCause(argumentErr).WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 46 return 47 } 48 arguments = append(arguments, argument) 49 break 50 case Json: 51 fv := target.ReadValue(rv) 52 if fv.Type().Kind() == reflect.Ptr { 53 if fv.IsNil() { 54 arguments = append(arguments, json.NullBytes) 55 break 56 } 57 fv = fv.Elem() 58 } 59 argument, argumentErr := json.Marshal(fv.Interface()) 60 if argumentErr != nil { 61 err = errors.Warning("sql: encode field value failed").WithCause(argumentErr).WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 62 return 63 } 64 arguments = append(arguments, json.RawMessage(argument)) 65 break 66 default: 67 err = errors.Warning("sql: field can not as argument").WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 68 return 69 } 70 } 71 return 72 } 73 74 func (spec *Specification) ArgumentByField(instance any, field string) (argument any, err error) { 75 rv := reflect.Indirect(reflect.ValueOf(instance)) 76 var target *Column 77 for _, column := range spec.Columns { 78 if column.Field == field { 79 target = column 80 break 81 } 82 } 83 if target == nil { 84 err = errors.Warning("sql: field was not found").WithMeta("table", rv.Type().String()).WithMeta("field", field) 85 return 86 } 87 switch target.Kind { 88 case Normal, Pk, Acb, Act, Amb, Amt, Adb, Adt, Aol: 89 fv := target.ReadValue(rv) 90 argument = fv.Interface() 91 break 92 case Reference: 93 refField, mapping, ok := target.Reference() 94 if !ok { 95 err = errors.Warning("sql: field is not reference").WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 96 return 97 } 98 fv := target.ReadValue(rv) 99 if fv.Type().Kind() == reflect.Ptr { 100 if fv.IsNil() { 101 return 102 } 103 fv = fv.Elem() 104 } 105 ref := fv.Interface() 106 argument, err = mapping.ArgumentByField(ref, refField) 107 if err != nil { 108 err = errors.Warning("sql: get field value failed").WithCause(err).WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 109 return 110 } 111 break 112 case Json: 113 fv := target.ReadValue(rv) 114 encode, encodeErr := json.Marshal(fv.Interface()) 115 if encodeErr != nil { 116 err = errors.Warning("sql: encode field value failed").WithCause(encodeErr).WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 117 return 118 } 119 argument = json.RawMessage(encode) 120 break 121 default: 122 err = errors.Warning("sql: field can not as argument").WithMeta("table", rv.Type().String()).WithMeta("field", target.Field) 123 return 124 } 125 return 126 }