253 lines
4.8 KiB
Go
253 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
_ "embed"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
//go:embed sql/schema.sql
|
|
var sqlSchema string
|
|
|
|
//go:embed sql/views.sql
|
|
var sqlViews string
|
|
|
|
type PostgresClient struct {
|
|
//TODO move context out of client
|
|
Ctx context.Context
|
|
Pool *pgxpool.Pool
|
|
}
|
|
|
|
func (db *PostgresClient) CreateOrReplaceSchema() error {
|
|
_, err := db.Pool.Exec(db.Ctx, sqlSchema)
|
|
return err
|
|
}
|
|
|
|
func (db *PostgresClient) CreateOrReplaceViews() error {
|
|
_, err := db.Pool.Exec(db.Ctx, sqlViews)
|
|
return err
|
|
}
|
|
|
|
// InsertMembres inserts a slice of Membre into a database, returning the amount inserted and any error encountered
|
|
func (d *PostgresClient) InsertMembres(membres ...Membre) (inserted int64, err error) {
|
|
select {
|
|
case <-d.Ctx.Done():
|
|
return inserted, fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
|
default:
|
|
tx, err := d.Pool.Begin(d.Ctx)
|
|
if err != nil {
|
|
return inserted, err
|
|
}
|
|
defer tx.Rollback(d.Ctx)
|
|
|
|
for i, membre := range membres {
|
|
if membre.ID == "" {
|
|
return inserted, fmt.Errorf("insertion ligne %d: membre requiert numéro étudiant valide", i)
|
|
}
|
|
|
|
result, err := tx.Exec(d.Ctx, `
|
|
INSERT INTO membres
|
|
(id, last_name, first_name, prefered_name, programme_id)
|
|
VALUES
|
|
($1, $2, $3, $4, $5)
|
|
ON CONFLICT (id) DO NOTHING;`,
|
|
membre.ID,
|
|
membre.LastName,
|
|
membre.FirstName,
|
|
membre.PreferedName,
|
|
membre.ProgrammeID,
|
|
)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
inserted += result.RowsAffected()
|
|
}
|
|
|
|
if err = tx.Commit(d.Ctx); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return inserted, err
|
|
}
|
|
}
|
|
|
|
func (d *PostgresClient) InsertProgrammes(programmes ...Programme) (inserted int64, err error) {
|
|
select {
|
|
case <-d.Ctx.Done():
|
|
return inserted, fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
|
default:
|
|
tx, err := d.Pool.Begin(d.Ctx)
|
|
if err != nil {
|
|
return inserted, err
|
|
}
|
|
defer tx.Rollback(d.Ctx)
|
|
|
|
for _, programme := range programmes {
|
|
if programme.ID == "" {
|
|
return 0, fmt.Errorf("Cannot insert programme with no programme_id")
|
|
}
|
|
|
|
result, err := tx.Exec(d.Ctx, `
|
|
INSERT INTO programmes
|
|
(id, name)
|
|
VALUES ($1, $2) ON CONFLICT DO NOTHING;`,
|
|
programme.ID,
|
|
programme.Name)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
inserted += result.RowsAffected()
|
|
}
|
|
|
|
if err := tx.Commit(d.Ctx); err != nil {
|
|
return inserted, err
|
|
}
|
|
|
|
return inserted, err
|
|
}
|
|
}
|
|
|
|
func (d *PostgresClient) GetMembre(membreID string) (membre Membre, err error) {
|
|
select {
|
|
case <-d.Ctx.Done():
|
|
err = fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
|
return
|
|
default:
|
|
if err = d.Pool.QueryRow(d.Ctx, `
|
|
SELECT
|
|
"membres".id,
|
|
"membres".last_name,
|
|
"membres".first_name,
|
|
"membres".prefered_name,
|
|
"membres".programme_id
|
|
FROM
|
|
"membres"
|
|
WHERE
|
|
"membres".id = $1
|
|
LIMIT
|
|
1;
|
|
`, membreID).Scan(
|
|
&membre.ID,
|
|
&membre.LastName,
|
|
&membre.FirstName,
|
|
&membre.PreferedName,
|
|
&membre.ProgrammeID,
|
|
); err != nil {
|
|
return
|
|
}
|
|
|
|
if membre.ID == "" {
|
|
return membre, fmt.Errorf("Aucun membre trouvé avec numéro '%s'", membre.ID)
|
|
}
|
|
|
|
return membre, nil
|
|
}
|
|
}
|
|
|
|
/*
|
|
func (d *PostgresClient) UpdateMembreName(membreID, newName string) (int64, error) {
|
|
result, err := d.Pool.Exec("UPDATE membres SET prefered_name = $1 WHERE id = $2;", newName, membreID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
rows, err := result.RowsAffected()
|
|
if err != nil {
|
|
return rows, err
|
|
}
|
|
|
|
return rows, nil
|
|
}
|
|
*/
|
|
|
|
func (d *PostgresClient) GetMembres(limit int) (membres []Membre, err error) {
|
|
select {
|
|
case <-d.Ctx.Done():
|
|
return nil, fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
|
default:
|
|
rows, err := d.Pool.Query(d.Ctx, `
|
|
SELECT
|
|
"membres".id,
|
|
"membres".last_name,
|
|
"membres".first_name,
|
|
"membres".prefered_name,
|
|
"membres".programme_id
|
|
FROM
|
|
"membres"
|
|
ORDER BY
|
|
"membres".id
|
|
LIMIT
|
|
$1;
|
|
`, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var membre Membre
|
|
|
|
if err = rows.Scan(
|
|
&membre.ID,
|
|
&membre.LastName,
|
|
&membre.FirstName,
|
|
&membre.PreferedName,
|
|
&membre.ProgrammeID,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
membres = append(membres, membre)
|
|
}
|
|
if rows.Err() != nil {
|
|
return membres, rows.Err()
|
|
}
|
|
|
|
return membres, nil
|
|
}
|
|
}
|
|
|
|
func (d *PostgresClient) GetProgrammes(limit int) (programmes []Programme, err error) {
|
|
select {
|
|
case <-d.Ctx.Done():
|
|
return nil, fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
|
default:
|
|
rows, err := d.Pool.Query(d.Ctx, `
|
|
SELECT
|
|
"programmes".id,
|
|
"programmes".name
|
|
FROM
|
|
"programmes"
|
|
ORDER BY
|
|
"programmes".id
|
|
LIMIT
|
|
$1;
|
|
`, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var programme Programme
|
|
|
|
if err = rows.Scan(
|
|
&programme.ID,
|
|
&programme.Name,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
programmes = append(programmes, programme)
|
|
}
|
|
if rows.Err() != nil {
|
|
return programmes, rows.Err()
|
|
}
|
|
|
|
return programmes, nil
|
|
}
|
|
}
|