Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/js/utils/util.go
2070 views
1
package utils
2
3
import (
4
"database/sql"
5
)
6
7
// SQLResult holds the result of a SQL query.
8
//
9
// It contains the count of rows, the columns present, and the actual row data.
10
type SQLResult struct {
11
Count int // Count is the number of rows returned.
12
Columns []string // Columns is the slice of column names.
13
Rows []interface{} // Rows is a slice of row data, where each row is a map of column name to value.
14
}
15
16
// UnmarshalSQLRows converts sql.Rows into a more structured SQLResult.
17
//
18
// This function takes *sql.Rows as input and attempts to unmarshal the data into
19
// a SQLResult struct. It handles different SQL data types by using the appropriate
20
// sql.Null* types during scanning. It returns a pointer to a SQLResult or an error.
21
//
22
// The function closes the sql.Rows when finished.
23
func UnmarshalSQLRows(rows *sql.Rows) (*SQLResult, error) {
24
defer func() {
25
_ = rows.Close()
26
}()
27
columnTypes, err := rows.ColumnTypes()
28
if err != nil {
29
return nil, err
30
}
31
result := &SQLResult{}
32
result.Columns, err = rows.Columns()
33
if err != nil {
34
return nil, err
35
}
36
37
count := len(columnTypes)
38
for rows.Next() {
39
result.Count++
40
scanArgs := make([]interface{}, count)
41
for i, v := range columnTypes {
42
switch v.DatabaseTypeName() {
43
case "VARCHAR", "TEXT", "UUID", "TIMESTAMP":
44
scanArgs[i] = new(sql.NullString)
45
case "BOOL":
46
scanArgs[i] = new(sql.NullBool)
47
case "INT4":
48
scanArgs[i] = new(sql.NullInt64)
49
default:
50
scanArgs[i] = new(sql.NullString)
51
}
52
}
53
err := rows.Scan(scanArgs...)
54
if err != nil {
55
// Return the result accumulated so far along with the error.
56
return result, err
57
}
58
masterData := make(map[string]interface{})
59
for i, v := range columnTypes {
60
if z, ok := (scanArgs[i]).(*sql.NullBool); ok {
61
masterData[v.Name()] = z.Bool
62
continue
63
}
64
65
if z, ok := (scanArgs[i]).(*sql.NullString); ok {
66
masterData[v.Name()] = z.String
67
continue
68
}
69
70
if z, ok := (scanArgs[i]).(*sql.NullInt64); ok {
71
masterData[v.Name()] = z.Int64
72
continue
73
}
74
75
if z, ok := (scanArgs[i]).(*sql.NullFloat64); ok {
76
masterData[v.Name()] = z.Float64
77
continue
78
}
79
80
if z, ok := (scanArgs[i]).(*sql.NullInt32); ok {
81
masterData[v.Name()] = z.Int32
82
continue
83
}
84
85
masterData[v.Name()] = scanArgs[i]
86
}
87
result.Rows = append(result.Rows, masterData)
88
}
89
return result, nil
90
}
91
92