From c5a355da9e823c1785891a45075d78a09f75abf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?France=CC=81=20Wilke?= <francewilke@gmail.com> Date: Thu, 31 Aug 2023 14:16:19 +0200 Subject: [PATCH] Add csv_utils --- csv_utils/csv_utils.go | 109 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 csv_utils/csv_utils.go diff --git a/csv_utils/csv_utils.go b/csv_utils/csv_utils.go new file mode 100644 index 0000000..c3c728d --- /dev/null +++ b/csv_utils/csv_utils.go @@ -0,0 +1,109 @@ +package csv_utils + +import ( + "bytes" + "database/sql" + "encoding/csv" + "fmt" + "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/date_utils" + "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/string_utils" +) + +// ToCsvBytes takes a list of header lines and data and returns the data in CSV format, as a byte slice. +func ToCSVBytes(generatedInfo []string, headers []string, data [][]string) ([]byte, error) { + b, err := getCSVData(generatedInfo, headers, data) + + return b.Bytes(), err +} + +func getCSVData(generatedInfo []string, headers []string, data [][]string) (*bytes.Buffer, error) { + buffer := bytes.NewBuffer([]byte{}) + csvWriter := csv.NewWriter(buffer) + + if len(generatedInfo) > 0 { + if err := csvWriter.Write(generatedInfo); err != nil { + return nil, err + } + } + + if err := csvWriter.Write(headers); err != nil { + return nil, err + } + + for _, v := range data { + if err := csvWriter.Write(v); err != nil { + return nil, err + } + } + + csvWriter.Flush() + + return buffer, nil +} + +// GetGenerationInfoForReport takes the csv event and returns the username and time of the request to generate the report. +func GetGenerationInfoForReport(username string) []string { + if username == "" { + username = "unknown user" + } + generatedAt := date_utils.CurrentDate().Format("02 Jan 2006 15:04") + + return []string{ + fmt.Sprint("Generated by ", username, " on ", generatedAt), + } +} + +// KeepLeadingZeroesInCsvField prepends a tab character to a string if it is numeric, so that leading zeroes will not be removed by the CSV +func KeepLeadingZeroesInCsvField(fieldString string) string { + if string_utils.IsNumericString(fieldString) { + if fieldString[0:1] == "0" { + return fmt.Sprintf("\t%s", fieldString) + } + } + return fieldString +} + +func SQLToCSVData(rows *sql.Rows) ([]byte, error) { + // Get the headers + columns, err := rows.Columns() + if err != nil { + return nil, err + } + + // Get the data + values := make([]interface{}, len(columns)) + scan_args := make([]interface{}, len(columns)) + for i := range values { + scan_args[i] = &values[i] + } + + var data [][]string + for rows.Next() { + row := make([]string, len(columns)) + + err = rows.Scan(scan_args...) + if err != nil { + return nil, err + } + + for i, _ := range columns { + var value interface{} + rawValue := values[i] + byteArray, ok := rawValue.([]byte) + if ok { + value = string(byteArray) + } else { + value = rawValue + } + if value == nil { + row[i] = "" + } else { + row[i] = fmt.Sprintf("%v", value) + } + } + data = append(data, row) + } + + b, err := getCSVData(nil, columns, data) + return b.Bytes(), err +} -- GitLab