mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 22:15:27 +00:00
* js hotfix: wrap javascript source in anon functions * mysql module improvements * misc mysql bugs * js vm pooling: soft deprecation + incentivised pooling * misc updates * disable interactsh failed test * disable interactsh.yaml integration test on win & mac
89 lines
2.3 KiB
Go
89 lines
2.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"database/sql"
|
|
)
|
|
|
|
// SQLResult holds the result of a SQL query.
|
|
//
|
|
// It contains the count of rows, the columns present, and the actual row data.
|
|
type SQLResult struct {
|
|
Count int // Count is the number of rows returned.
|
|
Columns []string // Columns is the slice of column names.
|
|
Rows []interface{} // Rows is a slice of row data, where each row is a map of column name to value.
|
|
}
|
|
|
|
// UnmarshalSQLRows converts sql.Rows into a more structured SQLResult.
|
|
//
|
|
// This function takes *sql.Rows as input and attempts to unmarshal the data into
|
|
// a SQLResult struct. It handles different SQL data types by using the appropriate
|
|
// sql.Null* types during scanning. It returns a pointer to a SQLResult or an error.
|
|
//
|
|
// The function closes the sql.Rows when finished.
|
|
func UnmarshalSQLRows(rows *sql.Rows) (*SQLResult, error) {
|
|
defer rows.Close()
|
|
columnTypes, err := rows.ColumnTypes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result := &SQLResult{}
|
|
result.Columns, err = rows.Columns()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
count := len(columnTypes)
|
|
for rows.Next() {
|
|
result.Count++
|
|
scanArgs := make([]interface{}, count)
|
|
for i, v := range columnTypes {
|
|
switch v.DatabaseTypeName() {
|
|
case "VARCHAR", "TEXT", "UUID", "TIMESTAMP":
|
|
scanArgs[i] = new(sql.NullString)
|
|
case "BOOL":
|
|
scanArgs[i] = new(sql.NullBool)
|
|
case "INT4":
|
|
scanArgs[i] = new(sql.NullInt64)
|
|
default:
|
|
scanArgs[i] = new(sql.NullString)
|
|
}
|
|
}
|
|
err := rows.Scan(scanArgs...)
|
|
if err != nil {
|
|
// Return the result accumulated so far along with the error.
|
|
return result, err
|
|
}
|
|
masterData := make(map[string]interface{})
|
|
for i, v := range columnTypes {
|
|
if z, ok := (scanArgs[i]).(*sql.NullBool); ok {
|
|
masterData[v.Name()] = z.Bool
|
|
continue
|
|
}
|
|
|
|
if z, ok := (scanArgs[i]).(*sql.NullString); ok {
|
|
masterData[v.Name()] = z.String
|
|
continue
|
|
}
|
|
|
|
if z, ok := (scanArgs[i]).(*sql.NullInt64); ok {
|
|
masterData[v.Name()] = z.Int64
|
|
continue
|
|
}
|
|
|
|
if z, ok := (scanArgs[i]).(*sql.NullFloat64); ok {
|
|
masterData[v.Name()] = z.Float64
|
|
continue
|
|
}
|
|
|
|
if z, ok := (scanArgs[i]).(*sql.NullInt32); ok {
|
|
masterData[v.Name()] = z.Int32
|
|
continue
|
|
}
|
|
|
|
masterData[v.Name()] = scanArgs[i]
|
|
}
|
|
result.Rows = append(result.Rows, masterData)
|
|
}
|
|
return result, nil
|
|
}
|