mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 20:25:27 +00:00
* chore: fix non-constant fmt string in call Signed-off-by: Dwi Siswanto <git@dw1.io> * build: bump all direct modules Signed-off-by: Dwi Siswanto <git@dw1.io> * chore(hosterrorscache): update import path Signed-off-by: Dwi Siswanto <git@dw1.io> * fix(charts): break changes Signed-off-by: Dwi Siswanto <git@dw1.io> * build: pinned `github.com/zmap/zcrypto` to v0.0.0-20240512203510-0fef58d9a9db Signed-off-by: Dwi Siswanto <git@dw1.io> * chore: golangci-lint auto fixes Signed-off-by: Dwi Siswanto <git@dw1.io> * chore: satisfy lints Signed-off-by: Dwi Siswanto <git@dw1.io> * build: migrate `github.com/xanzy/go-gitlab` => `gitlab.com/gitlab-org/api/client-go` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(json): update build constraints Signed-off-by: Dwi Siswanto <git@dw1.io> * chore: dont panicking on close err Signed-off-by: Dwi Siswanto <git@dw1.io> --------- Signed-off-by: Dwi Siswanto <git@dw1.io>
91 lines
2.3 KiB
Go
91 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 func() {
|
|
_ = 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
|
|
}
|