Implements csv parsing

This commit is contained in:
2016-01-17 12:58:59 +01:00
parent ab201424ad
commit b743fffb23
2 changed files with 128 additions and 19 deletions

View File

@@ -1,21 +1,129 @@
package main
import (
"encoding/csv"
"fmt"
"io"
"strconv"
"time"
)
// AlbumCsvReader can read Album definition from a csv file
type AlbumCsvReader struct {
r *csv.Reader
columns map[string]int
}
const (
cID string = "IdAlbum"
cISBN = "ISBN"
cSeries = "Serie"
cNum = "Num"
cNumA = "NumA"
cTitle = "Titre"
cEditor = "Editeur"
cCollection = "Collection"
cLegalDeposit = "DL"
cPrintDate = "AI"
cState = "Etat"
cPurchaseDate = "DateAchat"
cPerso1 = "Perso1"
cPerso2 = "Perso2"
)
var requiredFields = []string{cID, cISBN, cSeries, cNum, cNumA, cTitle, cEditor, cCollection, cLegalDeposit, cPrintDate, cState, cPurchaseDate, cPerso1, cPerso2}
// NewAlbumCsvReader creates a new AlbumCsvReader from a reader
func NewAlbumCsvReader(r io.Reader) *AlbumCsvReader {
return nil
func NewAlbumCsvReader(r io.Reader) (*AlbumCsvReader, error) {
res := &AlbumCsvReader{
r: csv.NewReader(r),
columns: make(map[string]int),
}
res.r.Comma = ';'
//reads the first line
colNames, err := res.r.Read()
if err != nil {
return nil, fmt.Errorf("album_csv: could not read first line: %s", err)
}
for i, n := range colNames {
res.columns[n] = i
}
missing := []string{}
for _, f := range requiredFields {
if _, ok := res.columns[f]; ok == false {
missing = append(missing, f)
}
}
if len(missing) != 0 {
return nil, fmt.Errorf("Invalid CSV file, missing required fields: %v", missing)
}
return res, nil
}
// Read get the next line in the CSV and return an Album or an error,
// or io.EOF if stream is closed
func (a *AlbumCsvReader) Read() (*Album, error) {
return nil, fmt.Errorf("Niot uyet implemented")
func (r *AlbumCsvReader) Read() (*Album, error) {
data, err := r.r.Read()
if err != nil {
return nil, err
}
res := &Album{
ISBN: data[r.columns[cISBN]],
Series: data[r.columns[cSeries]],
NumA: data[r.columns[cNumA]],
Title: data[r.columns[cTitle]],
Editor: data[r.columns[cEditor]],
Collection: data[r.columns[cCollection]],
}
ID, err := strconv.ParseInt(data[r.columns[cID]], 0, 64)
if err != nil {
return nil, fmt.Errorf("AlbumCsvReader: %s: %s", cID, err)
}
res.ID = uint64(ID)
if len(data[r.columns[cNum]]) == 0 {
res.Num = -1
} else {
n, err := strconv.ParseInt(data[r.columns[cNum]], 0, 32)
if err != nil {
return nil, fmt.Errorf("AlbumCsvReader: %s: %s", cNum, err)
}
res.Num = int(n)
}
if len(data[r.columns[cLegalDeposit]]) != 0 {
res.LegalDeposit, err = time.ParseInLocation("01/2006", data[r.columns[cLegalDeposit]], time.UTC)
if err != nil {
return nil, fmt.Errorf("AlbumCsvReader: %s: %s", cLegalDeposit, err)
}
}
if len(data[r.columns[cPrintDate]]) != 0 {
res.PrintDate, err = time.ParseInLocation("01/2006", data[r.columns[cPrintDate]], time.UTC)
if err != nil {
return nil, fmt.Errorf("AlbumCsvReader: %s: %s", cPrintDate, err)
}
}
state, err := strconv.ParseInt(data[r.columns[cState]], 0, 32)
if err != nil {
return nil, fmt.Errorf("AlbumCsvReader: %s: %s", cState, err)
}
res.State = AlbumState(state)
if len(data[r.columns[cPurchaseDate]]) != 0 {
res.PurchaseDate, err = time.ParseInLocation("02/01/2006", data[r.columns[cPurchaseDate]], time.UTC)
if err != nil {
return nil, fmt.Errorf("AlbumCsvReader: %s: %s", cPurchaseDate, err)
}
}
res.SatID = fmt.Sprintf("%s-%s", data[r.columns[cPerso1]], data[r.columns[cPerso2]])
return res, nil
}

View File

@@ -38,7 +38,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Editor: "Sarbacane",
Collection: "",
State: 1,
LegalDeposit: time.Date(2009, 10, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(2009, 10, 1, 0, 0, 0, 0, time.UTC),
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "RACO-1",
},
@@ -50,7 +50,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "Le roi Oscar et autres racontars",
Editor: "Sarbacane",
Collection: "",
LegalDeposit: time.Date(2011, 01, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(2011, 01, 1, 0, 0, 0, 0, time.UTC),
State: 2,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "RACO-2",
@@ -64,7 +64,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "''Atar Gull'' ou le destin d'un esclave modèle",
Editor: "Dargaud",
Collection: "Long Courrier",
LegalDeposit: time.Date(2011, 10, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(2011, 10, 1, 0, 0, 0, 0, time.UTC),
State: 3,
PurchaseDate: time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC),
SatID: "LONG-11",
@@ -78,7 +78,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "Tanino Liberatore",
Editor: "Kesselring",
Collection: "",
LegalDeposit: time.Date(1985, 12, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1985, 12, 1, 0, 0, 0, 0, time.UTC),
State: 4,
PurchaseDate: time.Date(2013, 12, 7, 0, 0, 0, 0, time.UTC),
SatID: "LIB-00",
@@ -105,7 +105,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "Humour noir et hommes en blanc",
Editor: "Éditions du Grésivaudan",
Collection: "",
LegalDeposit: time.Date(1972, 11, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1972, 11, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-1",
@@ -119,8 +119,8 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "Le Sport",
Editor: "Glénat",
Collection: "",
LegalDeposit: time.Date(1977, 10, 0, 0, 0, 0, 0, time.UTC),
PrintDate: time.Date(1977, 11, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1977, 10, 1, 0, 0, 0, 0, time.UTC),
PrintDate: time.Date(1977, 11, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-2",
@@ -134,8 +134,8 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "L'automobile",
Editor: "Glénat",
Collection: "",
LegalDeposit: time.Date(1978, 12, 0, 0, 0, 0, 0, time.UTC),
PrintDate: time.Date(1978, 12, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1978, 12, 1, 0, 0, 0, 0, time.UTC),
PrintDate: time.Date(1978, 12, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-3",
@@ -149,7 +149,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "...vice compris",
Editor: "Glénat",
Collection: "",
LegalDeposit: time.Date(1979, 10, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1979, 10, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-7",
@@ -163,7 +163,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "Savoir vivre",
Editor: "Glénat",
Collection: "",
LegalDeposit: time.Date(1981, 10, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1981, 10, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-5",
@@ -177,7 +177,7 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "La Bouffe",
Editor: "Glénat",
Collection: "",
LegalDeposit: time.Date(1982, 10, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1982, 10, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-4",
@@ -191,18 +191,19 @@ func (s *AlbumCsvReaderSuite) TestCanReadCsv(c *C) {
Title: "Le bricolage",
Editor: "Glénat",
Collection: "",
LegalDeposit: time.Date(1983, 12, 0, 0, 0, 0, 0, time.UTC),
LegalDeposit: time.Date(1983, 12, 1, 0, 0, 0, 0, time.UTC),
State: 0,
PurchaseDate: time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC),
SatID: "SERR-6",
},
}
r := NewAlbumCsvReader(strings.NewReader(csvData))
r, err := NewAlbumCsvReader(strings.NewReader(csvData))
c.Assert(err, IsNil)
for _, e := range expected {
res, err := r.Read()
if c.Check(err, IsNil) == true {
c.Check(res, Equals, e)
c.Check(*res, Equals, e, Commentf("expected: %+v actual: %+v", e, res))
}
}