Permettre upload par CSV #36
5 changed files with 52 additions and 15 deletions
|
@ -87,7 +87,7 @@ func (d *DataClient) InsertMembres(membres []models.Membre) (int64, error) {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, errors.New("Cannot insert membre with no membre_id")
|
return 0, errors.New("Cannot insert membre with no membre_id")
|
||||||
}
|
}
|
||||||
result, err := tx.NamedExec("INSERT INTO membres (id, last_name, first_name, prefered_name, programme_id) VALUES (:id, :last_name, :first_name, :prefered_name, :programme_id);", &membre)
|
result, err := tx.NamedExec("INSERT INTO membres (id, last_name, first_name, prefered_name, programme_id) VALUES (:id, :last_name, :first_name, :prefered_name, :programme_id) ON CONFLICT (id) DO NOTHING;", &membre)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -124,7 +124,7 @@ func (d *DataClient) InsertProgrammes(programmes []models.Programme) (int64, err
|
||||||
return 0, errors.New("Cannot insert programme with no programme_id")
|
return 0, errors.New("Cannot insert programme with no programme_id")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := tx.NamedExec("INSERT INTO programmes (id, titre) VALUES (:id, :titre);", &programme)
|
result, err := tx.NamedExec("INSERT INTO programmes (id, titre) VALUES (:id, :titre) ON CONFLICT DO NOTHING;", &programme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module git.agecem.com/agecem/bottin/v5
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gocarina/gocsv v0.0.0-20230616125104-99d496ca653d
|
||||||
github.com/jackc/pgx v3.6.2+incompatible
|
github.com/jackc/pgx v3.6.2+incompatible
|
||||||
github.com/jmoiron/sqlx v1.3.5
|
github.com/jmoiron/sqlx v1.3.5
|
||||||
github.com/labstack/echo/v4 v4.10.2
|
github.com/labstack/echo/v4 v4.10.2
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -66,6 +66,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/gocarina/gocsv v0.0.0-20230616125104-99d496ca653d h1:KbPOUXFUDJxwZ04vbmDOc3yuruGvVO+LOa7cVER3yWw=
|
||||||
|
github.com/gocarina/gocsv v0.0.0-20230616125104-99d496ca653d/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.agecem.com/agecem/bottin/v5/data"
|
"git.agecem.com/agecem/bottin/v5/data"
|
||||||
"git.agecem.com/agecem/bottin/v5/models"
|
"git.agecem.com/agecem/bottin/v5/models"
|
||||||
"git.agecem.com/agecem/bottin/v5/responses"
|
"git.agecem.com/agecem/bottin/v5/responses"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
|
"github.com/gocarina/gocsv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PostMembres(c echo.Context) error {
|
func PostMembres(c echo.Context) error {
|
||||||
|
@ -32,9 +36,21 @@ func PostMembres(c echo.Context) error {
|
||||||
return c.JSON(response.StatusCode, response)
|
return c.JSON(response.StatusCode, response)
|
||||||
}
|
}
|
||||||
case "text/csv":
|
case "text/csv":
|
||||||
response.StatusCode = http.StatusNotImplemented
|
body := c.Request().Body
|
||||||
response.Message = "Not Implemented"
|
if body == nil {
|
||||||
return c.JSON(response.StatusCode, response)
|
response.StatusCode = http.StatusBadRequest
|
||||||
|
response.Message = "Request body is empty"
|
||||||
|
return c.JSON(response.StatusCode, response)
|
||||||
|
}
|
||||||
|
defer body.Close()
|
||||||
|
|
||||||
|
// Parse the CSV data from the request body using gocsv.
|
||||||
|
if err := gocsv.Unmarshal(body, &membres); err != nil {
|
||||||
|
response.StatusCode = http.StatusBadRequest
|
||||||
|
response.Message = "Could not unmarshal into membres"
|
||||||
|
response.Error = err.Error()
|
||||||
|
return c.JSON(response.StatusCode, response)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
response.StatusCode = http.StatusBadRequest
|
response.StatusCode = http.StatusBadRequest
|
||||||
response.Message = "Invalid Content-Type"
|
response.Message = "Invalid Content-Type"
|
||||||
|
@ -85,9 +101,27 @@ func PostProgrammes(c echo.Context) error {
|
||||||
return c.JSON(response.StatusCode, response)
|
return c.JSON(response.StatusCode, response)
|
||||||
}
|
}
|
||||||
case "text/csv":
|
case "text/csv":
|
||||||
response.StatusCode = http.StatusNotImplemented
|
body := c.Request().Body
|
||||||
response.Message = "Not Implemented"
|
if body == nil {
|
||||||
return c.JSON(response.StatusCode, response)
|
response.StatusCode = http.StatusBadRequest
|
||||||
|
response.Message = "Request body is empty"
|
||||||
|
return c.JSON(response.StatusCode, response)
|
||||||
|
}
|
||||||
|
defer body.Close()
|
||||||
|
|
||||||
|
gocsv.SetCSVReader(func(in io.Reader) gocsv.CSVReader {
|
||||||
|
r := csv.NewReader(in)
|
||||||
|
r.Comma = ';'
|
||||||
|
return r // Allows use ; as delimiter
|
||||||
|
})
|
||||||
|
|
||||||
|
// Parse the CSV data from the request body using gocsv.
|
||||||
|
if err := gocsv.Unmarshal(body, &programmes); err != nil {
|
||||||
|
response.StatusCode = http.StatusBadRequest
|
||||||
|
response.Message = "Could not unmarshal into programmes"
|
||||||
|
response.Error = err.Error()
|
||||||
|
return c.JSON(response.StatusCode, response)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
response.StatusCode = http.StatusBadRequest
|
response.StatusCode = http.StatusBadRequest
|
||||||
response.Message = "Invalid Content-Type"
|
response.Message = "Invalid Content-Type"
|
||||||
|
|
|
@ -16,16 +16,16 @@ CREATE TABLE IF NOT EXISTS membres (
|
||||||
`
|
`
|
||||||
|
|
||||||
type Programme struct {
|
type Programme struct {
|
||||||
ID string `db:"id" json:"programme_id"`
|
ID string `db:"id" json:"programme_id" csv:"programme_id"`
|
||||||
Titre string `db:"titre" json:"nom_programme"`
|
Titre string `db:"titre" json:"nom_programme" csv:"nom_programme"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Membre struct {
|
type Membre struct {
|
||||||
ID string `db:"id" json:"membre_id"`
|
ID string `db:"id" json:"membre_id" csv:"membre_id"`
|
||||||
LastName string `db:"last_name" json:"last_name"`
|
LastName string `db:"last_name" json:"last_name" csv:"last_name"`
|
||||||
FirstName string `db:"first_name" json:"first_name"`
|
FirstName string `db:"first_name" json:"first_name" csv:"first_name"`
|
||||||
PreferedName string `db:"prefered_name" json:"prefered_name"`
|
PreferedName string `db:"prefered_name" json:"prefered_name" csv:"prefered_name"`
|
||||||
ProgrammeID string `db:"programme_id" json:"programme_id"`
|
ProgrammeID string `db:"programme_id" json:"programme_id" csv:"programme_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Entry interface {
|
type Entry interface {
|
||||||
|
|
Loading…
Reference in a new issue