github.com/angryronald/go-kit@v0.0.0-20240505173814-ff2bd9c79dbf/generic/repository/nosql/generic.utils.go (about)

     1  package nosql
     2  
     3  import (
     4  	"errors"
     5  	"reflect"
     6  	"strings"
     7  
     8  	"github.com/google/uuid"
     9  
    10  	"github.com/angryronald/go-kit/generic/repository"
    11  )
    12  
    13  // StructToMap converts a pointer to a struct into a map[string]interface{}
    14  func StructToMap(obj interface{}) (map[string]interface{}, error) {
    15  	if obj == nil {
    16  		return nil, errors.New("input object is nil")
    17  	}
    18  
    19  	value := reflect.ValueOf(obj)
    20  	if value.Kind() != reflect.Ptr || value.IsNil() {
    21  		return nil, errors.New("input is not a pointer to a struct")
    22  	}
    23  
    24  	value = value.Elem()
    25  	if value.Kind() != reflect.Struct {
    26  		return nil, errors.New("input is not a pointer to a struct")
    27  	}
    28  
    29  	result := make(map[string]interface{})
    30  	for i := 0; i < value.NumField(); i++ {
    31  		field := value.Type().Field(i)
    32  		result[field.Name] = value.Field(i).Interface()
    33  	}
    34  
    35  	return result, nil
    36  }
    37  
    38  func ConvertToArrayInterface(arrayPointerStruct interface{}) []interface{} {
    39  	// Get the type of the input slice
    40  	sliceType := reflect.TypeOf(arrayPointerStruct)
    41  	if sliceType.Kind() != reflect.Slice {
    42  		panic("Input is not a slice")
    43  	}
    44  
    45  	// Create a new slice of interfaces
    46  	interfaceSlice := make([]interface{}, 0)
    47  
    48  	// Convert each element of the input slice to interface{}
    49  	sliceValue := reflect.ValueOf(arrayPointerStruct)
    50  	for i := 0; i < sliceValue.Len(); i++ {
    51  		element := sliceValue.Index(i)
    52  		if element.Kind() != reflect.Ptr {
    53  			panic("Element is not a pointer")
    54  		}
    55  		interfaceSlice = append(interfaceSlice, element.Interface())
    56  	}
    57  
    58  	return interfaceSlice
    59  }
    60  
    61  func GetPropertyNamesAndValues(data interface{}) ([]string, []interface{}, error) {
    62  	if data == nil {
    63  		return nil, nil, repository.ErrOperationIsNotAllowed
    64  	}
    65  	dataType := reflect.TypeOf(data)
    66  	if dataType.Kind() != reflect.Ptr {
    67  		return nil, nil, errors.New("data must be a pointer to a struct")
    68  	}
    69  	dataType = dataType.Elem()
    70  
    71  	columns := make([]string, 0)
    72  	values := make([]interface{}, 0)
    73  
    74  	for i := 0; i < dataType.NumField(); i++ {
    75  		field := dataType.Field(i)
    76  		columnName := field.Name
    77  
    78  		// Skip unexported fields
    79  		if field.PkgPath != "" {
    80  			continue
    81  		}
    82  
    83  		columns = append(columns, columnName)
    84  		fieldValue := reflect.ValueOf(data).Elem().FieldByName(columnName).Interface()
    85  
    86  		// Check if the field is a pointer and if it's nil, replace with "NULL"
    87  		if reflect.ValueOf(fieldValue).Kind() == reflect.Ptr {
    88  			if reflect.ValueOf(fieldValue).IsNil() {
    89  				fieldValue = nil
    90  			} else {
    91  				fieldValue = reflect.ValueOf(fieldValue).Elem().Interface()
    92  			}
    93  		}
    94  
    95  		// Convert uuid.UUID fields to string
    96  		if _, ok := fieldValue.(uuid.UUID); ok {
    97  			fieldValue = fieldValue.(uuid.UUID).String()
    98  		}
    99  
   100  		// if _, ok := fieldValue.(time.Time); ok {
   101  		// 	fieldValue = gocql.UUIDFromTime(fieldValue.(time.Time))
   102  		// }
   103  
   104  		values = append(values, fieldValue)
   105  	}
   106  
   107  	return columns, values, nil
   108  }
   109  
   110  // GetPropertyNameToUpperCaseMapping returns a map of property names in upper case for the given struct.
   111  func GetPropertyNameTolowerCaseMapping(obj interface{}) (map[string]string, error) {
   112  	objValue := reflect.ValueOf(obj)
   113  	if objValue.Kind() != reflect.Struct {
   114  		return nil, errors.New("input must be a struct")
   115  	}
   116  
   117  	mapping := make(map[string]string)
   118  	objType := objValue.Type()
   119  
   120  	for i := 0; i < objValue.NumField(); i++ {
   121  		field := objType.Field(i)
   122  		fieldName := field.Name
   123  		upperCaseFieldName := strings.ToLower(fieldName)
   124  		mapping[fieldName] = upperCaseFieldName
   125  	}
   126  
   127  	return mapping, nil
   128  }