2020-08-06 20:58:47 +03:00
|
|
|
package raww
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"strconv"
|
2023-05-11 05:03:45 +03:00
|
|
|
"sync"
|
2020-08-06 20:58:47 +03:00
|
|
|
"time"
|
|
|
|
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/kind"
|
|
|
|
"github.com/neilotoole/sq/libsq/core/stringz"
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
"github.com/neilotoole/sq/cli/output"
|
|
|
|
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/sqlz"
|
2020-08-06 20:58:47 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// recordWriter implements output.RecordWriter for raw output.
|
|
|
|
// This is typically used to output a single blob result, such
|
|
|
|
// as a gif etc. The elements of each record are directly
|
|
|
|
// written to the backing writer without any separator, or
|
|
|
|
// encoding, etc.
|
|
|
|
type recordWriter struct {
|
2023-05-11 05:03:45 +03:00
|
|
|
mu sync.Mutex
|
2020-08-06 20:58:47 +03:00
|
|
|
out io.Writer
|
2023-05-07 05:36:34 +03:00
|
|
|
pr *output.Printing
|
2020-08-06 20:58:47 +03:00
|
|
|
recMeta sqlz.RecordMeta
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewRecordWriter returns an output.RecordWriter instance for
|
|
|
|
// raw output. This is typically used to output a single blob result,
|
|
|
|
// such as a gif etc. The elements of each record are directly
|
|
|
|
// written to the backing writer without any separator, or
|
|
|
|
// encoding, etc..
|
2023-05-07 05:36:34 +03:00
|
|
|
func NewRecordWriter(out io.Writer, pr *output.Printing) output.RecordWriter {
|
|
|
|
return &recordWriter{out: out, pr: pr}
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Open implements output.RecordWriter.
|
|
|
|
func (w *recordWriter) Open(recMeta sqlz.RecordMeta) error {
|
|
|
|
w.recMeta = recMeta
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// WriteRecords implements output.RecordWriter.
|
|
|
|
func (w *recordWriter) WriteRecords(recs []sqlz.Record) error {
|
2023-05-11 05:03:45 +03:00
|
|
|
w.mu.Lock()
|
|
|
|
defer w.mu.Unlock()
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
if len(recs) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, rec := range recs {
|
|
|
|
for i, val := range rec {
|
|
|
|
switch val := val.(type) {
|
|
|
|
case nil:
|
|
|
|
case *[]byte:
|
|
|
|
_, _ = w.out.Write(*val)
|
|
|
|
case *string:
|
|
|
|
_, _ = w.out.Write([]byte(*val))
|
|
|
|
case *bool:
|
|
|
|
fmt.Fprint(w.out, strconv.FormatBool(*val))
|
|
|
|
case *int64:
|
|
|
|
fmt.Fprint(w.out, strconv.FormatInt(*val, 10))
|
|
|
|
case *float64:
|
|
|
|
fmt.Fprint(w.out, stringz.FormatFloat(*val))
|
|
|
|
case *time.Time:
|
2022-12-18 08:16:10 +03:00
|
|
|
switch w.recMeta[i].Kind() { //nolint:exhaustive
|
2020-08-06 20:58:47 +03:00
|
|
|
default:
|
2023-05-07 05:36:34 +03:00
|
|
|
fmt.Fprint(w.out, w.pr.FormatDatetime(*val))
|
2020-08-23 13:42:15 +03:00
|
|
|
case kind.Time:
|
2023-05-07 05:36:34 +03:00
|
|
|
fmt.Fprint(w.out, w.pr.FormatTime(*val))
|
2020-08-23 13:42:15 +03:00
|
|
|
case kind.Date:
|
2023-05-07 05:36:34 +03:00
|
|
|
fmt.Fprint(w.out, w.pr.FormatDate(*val))
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
// should never happen
|
|
|
|
fmt.Fprintf(w.out, "%s", val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flush implements output.RecordWriter.
|
|
|
|
func (w *recordWriter) Flush() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close implements output.RecordWriter.
|
|
|
|
func (w *recordWriter) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|