geziyor/exporter/csv.go
Musab Gültekin ddff3aee25 Request cancellations support added to Middlewares.
Some core functions refactored as middlewares.
Fixed race condition in exporting system. Now, only one goroutine will be responsible for exporting. This fixes concurrency issues on writing.
2019-06-15 22:27:46 +03:00

66 lines
1.3 KiB
Go

package exporter
import (
"encoding/csv"
"fmt"
"log"
"os"
"reflect"
"sync"
)
// CSVExporter exports response data as CSV streaming file
type CSVExporter struct {
FileName string
once sync.Once
mut sync.Mutex
writer *csv.Writer
}
// Export exports response data as CSV streaming file
func (e *CSVExporter) Export(exports chan interface{}) {
// Default filename
if e.FileName == "" {
e.FileName = "out.csv"
}
// Create file
e.once.Do(func() {
newFile, err := os.OpenFile(e.FileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
fmt.Fprintf(os.Stderr, "output file creation error: %v", err)
return
}
e.writer = csv.NewWriter(newFile)
})
// Export data as responses came
for res := range exports {
var values []string
// Detect type and extract CSV values
val := reflect.ValueOf(res)
switch val.Kind() {
case reflect.Slice:
for i := 0; i < val.Len(); i++ {
values = append(values, fmt.Sprint(val.Index(i)))
}
//case reflect.Map:
// iter := val.MapRange()
// for iter.Next() {
// values = append(values, fmt.Sprint(iter.Value()))
// }
}
// Write to file
if err := e.writer.Write(values); err != nil {
log.Printf("CSV writing error on exporter: %v\n", err)
}
}
e.writer.Flush()
}