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 }