Implements csv parsing
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user