csvhandler

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 28, 2021 License: MIT Imports: 8 Imported by: 0

README

CSVHandler

PkgGoDev CI codecov

Golang built-in encoding/csv package can be tedious to use as it handles records as low level types []string, forcing users to access field using indexes.
This package aims to ease this use by allowing direct access with the column name, with an API close to encoding/csv.

For a usage closer to encoding/json with marshal/unmarshal functions to/from a struct, consider using other package such as github.com/jszwec/csvutil or github.com/gocarina/gocsv.

Installation

go get github.com/jcuvillier/csvhandler

Reader

csvInput := bytes.NewBuffer([]byte(`
first_name,last_name,age
Holly,Franklin,27
Giacobo,Tolumello,18`,
))

reader, _ := csvhandler.NewReader(csv.NewReader(csvInput))
record, _ := reader.Read()
record.Get("first_name") // returns Holly
record.GetInt("age")     // return 27

Writer

// Create a writer to stdout with header "first_name,last_name,age"
writer, _ := csvhandler.NewWriter( csv.NewWriter(os.Stdout), "first_name", "last_name","age")

// Write header line
writer.WriteHeader() // Writes first_name,last_name,age

// Create a record to be written
record := NewRecord()
record.Set("first_name", "Holly")
record.Set("last_name", "Franklin")
record.Set("age", 27)
writer.Write(record) // Writes Holly,Franklin,27

Empty and default values

If a field is not specified, Writer.EmptyValue is used. A default value can also be provided with Writer.SetDefault function.

writer, _ := csvhandler.NewWriter( csv.NewWriter(os.Stdout), "first_name", "last_name","age")
writer.SetDefault("age", 18)

record := NewRecord()
record.Set("first_name", "Holly")
writer.Write(record) // Writes Holly,,18

Formatter

Formatters can be defined and used when writting records.

// Formatter is the function that returns a string formatted version of the given value or an error.
type Formatter func(interface{}) (string, error)
Built-in formatters

This library provides built-in formatters:

  • StringFormatter
// StringFormatter returns a new formatter that uses the given format.
// Format is applied using `fmt.Sprintf`
func StringFormatter(format string) Formatter
  • TimeFormatter
// TimeFormatter returns a new formatter that uses the given layout to format a time.
// Only time.Time and *time.Time are allowed as value for the returned formatter.
func TimeFormatter(layout string) Formatter
How to specify formatter ?

Formatters can be specified when setting a value to a record

record.Set("first_name", "Holly", StringFormatter("My name is %v")) // My name is Holy

or when setting a default value

writer.SetDefault("age", 18, StringFormatter("%v (default)")) // 18 (default)

If no formatter is specified, the following defaultFormatter is applied:

// defaultFormatter is the formatter used when no formatter are specified by caller.
// It printfs the value with a basic `fmt.Sprintf("%v")`
func defaultFormatter(value interface{}) (string, error) {
	return fmt.Sprintf("%v", value), nil
}

It is also possible to specify a formatter to be applied for a given column, this formatter is chained with any formatter previously specified.

writer.SetFormatter("last_update", TimeFormatter(time.UnixDate)) // Tue Jan 26 10:20:08 CET 2021
Chained formatter

Formatters are passed using a variadic to make it optionnal. Therefore it is possible to specify multiple formatter, in such case, they are chained.

record.Set("time", time.Now(), TimeFormatter("Monday 02 Jan 2006"), StringFormatter("Today is %v")) // Today is Tuesday 26 Jan 2021

Record

Get fields

Record holds the fields for a given entry.
It offers utility functions to Get field based on the column name to a given type, for instance:

GetInt(key string) (int, error)

Supported types are string, bool, int, int64, float64, time.Time and timne.Duration.

Print fields

You can also print as key/value pairs a record by giving the column name.

r.Println("first_name", "last_name") // prints to stdout "first_name='Holly' last_name='Franklin'"

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrDuplicateKey

type ErrDuplicateKey struct {
	// contains filtered or unexported fields
}

ErrDuplicateKey means a duplicate key is detected within header

func (ErrDuplicateKey) Error

func (e ErrDuplicateKey) Error() string

type ErrUnknownKey

type ErrUnknownKey struct {
	// contains filtered or unexported fields
}

ErrUnknownKey means a requested key does not exist within header

func (ErrUnknownKey) Error

func (e ErrUnknownKey) Error() string

type ErrWrongType

type ErrWrongType struct {
	// contains filtered or unexported fields
}

ErrWrongType means the field with the requested key is not the expected type

func (ErrWrongType) Error

func (e ErrWrongType) Error() string

type Formatter added in v0.1.1

type Formatter func(interface{}) (string, error)

Formatter is the function that returns a string formatted version of the given value or an error.

func StringFormatter added in v0.1.1

func StringFormatter(format string) Formatter

StringFormatter returns a new formatter that uses the given format. Format is applied using `fmt.Sprintf`

func TimeFormatter added in v0.1.1

func TimeFormatter(layout string) Formatter

TimeFormatter returns a new formatter that uses the given layout to format a time. Only time.Time and *time.Time are allowed as value for the returned formatter.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader reads records from a CSV-encoded file.

It internally wraps a `encoding/csv.Reader` and uses it to read the data. It also holds a map keeping the column names with their indexes. This Reader is thread safe.

func NewReader

func NewReader(r *csv.Reader, header ...string) (*Reader, error)

NewReader creates a new Reader from the given `encoding/csv.Reader`.

If header is empty NewReader will read the first record and extract column names. As it wraps `encoding/csv.Reader`, any errors returned by the `Read` function can be returned here (including io.EOF is the reader is empty).

If a duplicate is detected among column names, ErrDuplicateKey is returned.

func (*Reader) Read

func (r *Reader) Read() (*Record, error)

Read reads one record (a slice of fields) from handler.

If the record has an unexpected number of fields, Read returns the record along with the error csv.ErrFieldCount. If there is no data left to be read, Read returns nil, io.EOF.

func (*Reader) ReadAll

func (r *Reader) ReadAll() ([]*Record, error)

ReadAll ReadAll reads all the remaining records.

As for the underlying `csv.Reader`, a successful call returns err == nil, not err == io.EOF. Because ReadAll is defined to read until EOF, it does not treat end of file as an error to be reported.

type Record

type Record struct {
	// contains filtered or unexported fields
}

Record holds the fields for a given entry. It offers utility functions to access field based on the column name

func NewRecord

func NewRecord() *Record

NewRecord returns a new empty Record.

func (*Record) Fprintln

func (r *Record) Fprintln(w io.Writer, columns ...string) error

Fprintln prints into the given writer each given column with a 'key=value' format. For instance, Fprintln(w, "first_name", "last_name") writes "first_name='John' last_name='Smith'" Expected errors are the same Get() may return

func (*Record) Get

func (r *Record) Get(key string) (string, error)

Get returns as a string the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned.

func (*Record) GetBool

func (r *Record) GetBool(key string) (bool, error)

GetBool returns as a boolean the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned. If the field is not the expected type, ErrWrongType is returned.

func (*Record) GetDuration

func (r *Record) GetDuration(key string) (time.Duration, error)

GetDuration returns as a time.Duration the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned. If the field cannot be parsed as a duration, ErrWrongType is returned.

func (*Record) GetFloat64

func (r *Record) GetFloat64(key string) (float64, error)

GetFloat64 returns as an float the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned. If the field is not the expected type, ErrWrongType is returned.

func (*Record) GetInt

func (r *Record) GetInt(key string) (int, error)

GetInt returns as an integer the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned. If the field is not the expected type, ErrWrongType is returned.

func (*Record) GetInt64

func (r *Record) GetInt64(key string) (int64, error)

GetInt64 returns as an integer64 the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned. If the field is not the expected type, ErrWrongType is returned.

func (*Record) GetTime

func (r *Record) GetTime(layout, key string) (time.Time, error)

GetTime returns as a time.Time the field corresponding to the given key. If the key is missing, ErrUnknownKey is returned. If the field cannot be parsed as a time using the given layout, ErrWrongType is returned.

func (*Record) Println

func (r *Record) Println(columns ...string) error

Println prints into the standard output each given column with a 'key=value' format. For instance, Fprintln(w, "first_name", "last_name") writes "first_name='John' last_name='Smith'" Expected errors are the same Get() may return

func (*Record) Set

func (r *Record) Set(key string, value interface{}, formatter ...Formatter)

Set sets the given value to the given key.

Calling twice this function with the same key will override the value.

Optionally, caller can define formatters. If none are provided, `defaultFormatter` is used (basic `fmt.Sprintf("%v",...)`) If multiple formatters are provided they are chained using `chainFormatter`.

type Writer

type Writer struct {
	EmptyValue string
	// contains filtered or unexported fields
}

A Writer writes records using CSV encoding.

It internally uses a `encoding/csv.Writer` to write the records.

func NewWriter

func NewWriter(w *csv.Writer, header ...string) (*Writer, error)

NewWriter creates a new Writer from the given `encoding/csv.Wrtiter` and header.

If a duplicate is detected among column names, ErrDuplicateKey is returned.

func (*Writer) SetDefault

func (w *Writer) SetDefault(key string, value interface{}, formatter ...Formatter)

SetDefault sets the default value to be used if there is no value for this key in the record.

If the defined value is nil, default value is used.

func (*Writer) SetFormatter added in v0.1.1

func (w *Writer) SetFormatter(key string, formatter ...Formatter)

SetFormatter sets the formatter to be used

func (*Writer) Write

func (w *Writer) Write(r *Record) error

Write writes the given record as a new line.

Field delimiter used is the one specified in the `encoding/csv.Writer` given when creating this Writer. Fields are written in the header order specified in `NewWriter` function. If field is not specified in the record, a specified default value (see function SetDefault())

can be used, otherwise EmptyValue is used.

Fields with key not in header will be ignored.

func (*Writer) WriteAll

func (w *Writer) WriteAll(r []*Record) error

WriteAll writes all the given records using the Write function.

func (*Writer) WriteHeader

func (w *Writer) WriteHeader() error

WriteHeader writes the header line of the CSV.

Field delimiter used is the one specified in the `encoding/csv.Writer` given when creating this Writer. Header keys are written in the same order as specified in `NewWriter` function.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL