MCPcopy Create free account
hub / github.com/Apress/pro-go / scanIntoStruct

Function scanIntoStruct

26 - Databases/data/database.go:30–77  ·  view source on GitHub ↗
(rows *sql.Rows, target interface{})

Source from the content-addressed store, hash-verified

28}
29
30func scanIntoStruct(rows *sql.Rows, target interface{}) (results interface{},
31 err error) {
32 targetVal := reflect.ValueOf(target)
33 if (targetVal.Kind() == reflect.Ptr) {
34 targetVal = targetVal.Elem()
35 }
36 if (targetVal.Kind() != reflect.Struct) {
37 return
38 }
39 colNames, _ := rows.Columns()
40 colTypes, _ := rows.ColumnTypes()
41 references := []interface{} {}
42 fieldVal := reflect.Value{}
43 var placeholder interface{}
44
45 for i, colName := range colNames {
46 colNameParts := strings.Split(colName, ".")
47 fieldVal = targetVal.FieldByName(colNameParts[0])
48 if (fieldVal.IsValid() && fieldVal.Kind() == reflect.Struct &&
49 len(colNameParts) > 1 ) {
50 var namePart string
51 for _, namePart = range colNameParts[1:] {
52 compFunction := matchColName(namePart)
53 fieldVal = fieldVal.FieldByNameFunc(compFunction)
54 }
55 }
56
57 if (!fieldVal.IsValid() ||
58 !colTypes[i].ScanType().ConvertibleTo(fieldVal.Type())) {
59 references = append(references, &placeholder)
60 } else if (fieldVal.Kind() != reflect.Ptr && fieldVal.CanAddr()) {
61 fieldVal = fieldVal.Addr()
62 references = append(references, fieldVal.Interface())
63 }
64 }
65
66 resultSlice := reflect.MakeSlice(reflect.SliceOf(targetVal.Type()), 0, 10)
67 for rows.Next() {
68 err = rows.Scan(references...)
69 if (err == nil) {
70 resultSlice = reflect.Append(resultSlice, targetVal)
71 } else {
72 break
73 }
74 }
75 results = resultSlice.Interface()
76 return
77}
78
79
80func matchColName(colName string) func(string) bool {

Callers 1

queryDatabaseFunction · 0.85

Calls 1

matchColNameFunction · 0.85

Tested by

no test coverage detected