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  }