Version 7 #53
1 changed files with 120 additions and 124 deletions
208
db.go
208
db.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
)
|
)
|
||||||
|
@ -11,6 +12,7 @@ import (
|
||||||
var sqlSchema string
|
var sqlSchema string
|
||||||
|
|
||||||
type PostgresClient struct {
|
type PostgresClient struct {
|
||||||
|
//TODO move context out of client
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
Pool *pgxpool.Pool
|
Pool *pgxpool.Pool
|
||||||
}
|
}
|
||||||
|
@ -20,142 +22,92 @@ func (db *PostgresClient) CreateOrReplaceSchema() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// DataClient is a postgres client based on sqlx
|
|
||||||
type DataClient struct {
|
|
||||||
PostgresConnection PostgresConnection
|
|
||||||
DB sqlx.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostgresConnection struct {
|
|
||||||
User string
|
|
||||||
Password string
|
|
||||||
Database string
|
|
||||||
Host string
|
|
||||||
Port int
|
|
||||||
SSL bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDataClientFromViper() (*DataClient, error) {
|
|
||||||
client, err := NewDataClient(
|
|
||||||
PostgresConnection{
|
|
||||||
User: viper.GetString(cmd.ViperDBHost),
|
|
||||||
Password: viper.GetString(cmd.ViperDBPassword),
|
|
||||||
Host: viper.GetString(cmd.ViperDBHost),
|
|
||||||
Database: viper.GetString(cmd.ViperDBDatabase),
|
|
||||||
Port: viper.GetInt(cmd.ViperDBPort),
|
|
||||||
})
|
|
||||||
|
|
||||||
return client, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDataClient(connection PostgresConnection) (*DataClient, error) {
|
|
||||||
client := &DataClient{PostgresConnection: connection}
|
|
||||||
|
|
||||||
connectionString := fmt.Sprintf("postgres://%s:%s@%s:%d/%s",
|
|
||||||
client.PostgresConnection.User,
|
|
||||||
client.PostgresConnection.Password,
|
|
||||||
client.PostgresConnection.Host,
|
|
||||||
client.PostgresConnection.Port,
|
|
||||||
client.PostgresConnection.Database,
|
|
||||||
)
|
|
||||||
|
|
||||||
db, err := sqlx.Connect("pgx", connectionString)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
client.DB = *db
|
|
||||||
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DataClient) Seed() (int64, error) {
|
|
||||||
result, err := d.DB.Exec(sqlSchema)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := result.RowsAffected()
|
|
||||||
if err != nil {
|
|
||||||
return rows, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return rows, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertMembres inserts a slice of Membre into a database, returning the amount inserted and any error encountered
|
// InsertMembres inserts a slice of Membre into a database, returning the amount inserted and any error encountered
|
||||||
func (d *DataClient) InsertMembres(membres []Membre) (int64, error) {
|
func (d *PostgresClient) InsertMembres(membres []Membre) (inserted int64, err error) {
|
||||||
var rowsInserted int64
|
select {
|
||||||
tx, err := d.DB.Beginx()
|
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 {
|
if err != nil {
|
||||||
return rowsInserted, err
|
return inserted, err
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback(d.Ctx)
|
||||||
|
|
||||||
for _, membre := range membres {
|
for i, membre := range membres {
|
||||||
if membre.ID == "" {
|
if membre.ID == "" {
|
||||||
return 0, errors.New("Cannot insert membre with no membre_id")
|
return inserted, fmt.Errorf("insertion ligne %d: membre requiert numéro étudiant valide", i)
|
||||||
}
|
}
|
||||||
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)
|
|
||||||
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := result.RowsAffected()
|
inserted += result.RowsAffected()
|
||||||
if err != nil {
|
}
|
||||||
|
|
||||||
|
if err = tx.Commit(d.Ctx); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rowsInserted += rows
|
return inserted, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tx.Commit()
|
|
||||||
if err != nil {
|
|
||||||
return rowsInserted, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return rowsInserted, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataClient) InsertProgrammes(programmes []Programme) (int64, error) {
|
func (d *PostgresClient) InsertProgrammes(programmes []Programme) (inserted int64, err error) {
|
||||||
var rowsInserted int64
|
select {
|
||||||
tx, err := d.DB.Beginx()
|
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 {
|
if err != nil {
|
||||||
return rowsInserted, err
|
return inserted, err
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback(d.Ctx)
|
||||||
|
|
||||||
for _, programme := range programmes {
|
for _, programme := range programmes {
|
||||||
if programme.ID == "" {
|
if programme.ID == "" {
|
||||||
return 0, errors.New("Cannot insert programme with no programme_id")
|
return 0, fmt.Errorf("Cannot insert programme with no programme_id")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := tx.NamedExec("INSERT INTO programmes (id, titre) VALUES (:id, :titre) ON CONFLICT DO NOTHING;", &programme)
|
result, err := tx.Exec(d.Ctx, `
|
||||||
|
INSERT INTO programmes
|
||||||
|
(id, titre)
|
||||||
|
VALUES ($1, $2) ON CONFLICT DO NOTHING;`,
|
||||||
|
programme.ID,
|
||||||
|
programme.Titre)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := result.RowsAffected()
|
inserted += result.RowsAffected()
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rowsInserted += rows
|
if err := tx.Commit(d.Ctx); err != nil {
|
||||||
|
return inserted, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tx.Commit()
|
return inserted, err
|
||||||
if err != nil {
|
|
||||||
return rowsInserted, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rowsInserted, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataClient) GetMembre(membreID string) (Membre, error) {
|
/*
|
||||||
|
func (d *PostgresClient) GetMembre(membreID string) (Membre, error) {
|
||||||
var membre Membre
|
var membre Membre
|
||||||
|
|
||||||
rows, err := d.DB.Queryx("SELECT * FROM membres WHERE id = $1 LIMIT 1;", membreID)
|
rows, err := d.Pool.Queryx("SELECT * FROM membres WHERE id = $1 LIMIT 1;", membreID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return membre, err
|
return membre, err
|
||||||
}
|
}
|
||||||
|
@ -173,9 +125,11 @@ func (d *DataClient) GetMembre(membreID string) (Membre, error) {
|
||||||
|
|
||||||
return membre, nil
|
return membre, nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func (d *DataClient) UpdateMembreName(membreID, newName string) (int64, error) {
|
/*
|
||||||
result, err := d.DB.Exec("UPDATE membres SET prefered_name = $1 WHERE id = $2;", newName, membreID)
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -187,8 +141,50 @@ func (d *DataClient) UpdateMembreName(membreID, newName string) (int64, error) {
|
||||||
|
|
||||||
return rows, nil
|
return rows, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataClient) GetMembres() (membres []Membre, err error) {
|
|
||||||
return membres, d.DB.Select(&membres, "SELECT * FROM membres;")
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
func (d *PostgresClient) GetMembres() (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
|
||||||
|
LIMIT
|
||||||
|
10000
|
||||||
|
ORDER BY
|
||||||
|
membres.id;`)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue