...
1 package exp
2
3 import (
4 "reflect"
5 "sort"
6
7 "github.com/doug-martin/goqu/v9/internal/util"
8 )
9
10
11 type Record map[string]interface{}
12
13 func (r Record) Cols() []string {
14 cols := make([]string, 0, len(r))
15 for col := range r {
16 cols = append(cols, col)
17 }
18 sort.Strings(cols)
19 return cols
20 }
21
22 func NewRecordFromStruct(i interface{}, forInsert, forUpdate bool) (r Record, err error) {
23 value := reflect.ValueOf(i)
24 if value.IsValid() {
25 cm, err := util.GetColumnMap(value.Interface())
26 if err != nil {
27 return nil, err
28 }
29 cols := cm.Cols()
30 r = make(map[string]interface{}, len(cols))
31 for _, col := range cols {
32 f := cm[col]
33 if !shouldSkipField(f, forInsert, forUpdate) {
34 if ok, fieldVal := getFieldValue(value, f); ok {
35 r[f.ColumnName] = fieldVal
36 }
37 }
38 }
39 }
40 return
41 }
42
43 func shouldSkipField(f util.ColumnData, forInsert, forUpdate bool) bool {
44 shouldSkipInsert := forInsert && !f.ShouldInsert
45 shouldSkipUpdate := forUpdate && !f.ShouldUpdate
46 return shouldSkipInsert || shouldSkipUpdate
47 }
48
49 func getFieldValue(val reflect.Value, f util.ColumnData) (ok bool, fieldVal interface{}) {
50 if v, isAvailable := util.SafeGetFieldByIndex(val, f.FieldIndex); !isAvailable {
51 return false, nil
52 } else if f.DefaultIfEmpty && util.IsEmptyValue(v) {
53 return true, Default()
54 } else if v.IsValid() {
55 return true, v.Interface()
56 } else {
57 return true, reflect.Zero(f.GoType).Interface()
58 }
59 }
60
View as plain text