2024-06-06 01:40:56 -04:00
package main
2023-03-06 14:01:18 -05:00
import (
2024-06-06 01:40:56 -04:00
"context"
_ "embed"
2023-03-06 14:01:18 -05:00
2024-06-06 01:40:56 -04:00
"github.com/jackc/pgx/v5/pgxpool"
2023-03-06 14:01:18 -05:00
)
2024-06-06 01:40:56 -04:00
//go:embed sql/schema.sql
var sqlSchema string
type PostgresClient struct {
Ctx context . Context
Pool * pgxpool . Pool
}
func ( db * PostgresClient ) CreateOrReplaceSchema ( ) error {
_ , err := db . Pool . Exec ( db . Ctx , sqlSchema )
return err
}
/ *
2023-05-29 18:19:31 -04:00
// DataClient is a postgres client based on sqlx
type DataClient struct {
PostgresConnection PostgresConnection
DB sqlx . DB
}
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
type PostgresConnection struct {
User string
Password string
Database string
Host string
Port int
SSL bool
2023-03-06 14:01:18 -05:00
}
2023-06-02 02:44:11 -04:00
func NewDataClientFromViper ( ) ( * DataClient , error ) {
client , err := NewDataClient (
PostgresConnection {
2024-06-06 01:40:56 -04:00
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 ) ,
2023-06-02 02:44:11 -04:00
} )
return client , err
}
2023-05-29 18:19:31 -04:00
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 ,
)
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
db , err := sqlx . Connect ( "pgx" , connectionString )
if err != nil {
return nil , err
}
client . DB = * db
return client , nil
}
func ( d * DataClient ) Seed ( ) ( int64 , error ) {
2024-06-06 01:40:56 -04:00
result , err := d . DB . Exec ( sqlSchema )
2023-05-29 18:19:31 -04:00
if err != nil {
return 0 , err
}
rows , err := result . RowsAffected ( )
if err != nil {
return rows , err
}
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
return rows , nil
}
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
// InsertMembres inserts a slice of Membre into a database, returning the amount inserted and any error encountered
2024-06-06 01:40:56 -04:00
func ( d * DataClient ) InsertMembres ( membres [ ] Membre ) ( int64 , error ) {
2023-05-29 18:19:31 -04:00
var rowsInserted int64
tx , err := d . DB . Beginx ( )
if err != nil {
return rowsInserted , err
}
2024-02-14 14:13:01 -05:00
defer tx . Rollback ( )
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
for _ , membre := range membres {
if membre . ID == "" {
return 0 , errors . New ( "Cannot insert membre with no membre_id" )
}
2023-09-05 18:03:28 -04:00
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 )
2023-05-29 18:19:31 -04:00
if err != nil {
return 0 , err
2023-03-06 14:01:18 -05:00
}
2023-05-29 18:19:31 -04:00
rows , err := result . RowsAffected ( )
if err != nil {
return 0 , err
}
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
rowsInserted += rows
2023-03-06 14:01:18 -05:00
}
2023-05-29 18:19:31 -04:00
err = tx . Commit ( )
2023-03-06 14:01:18 -05:00
if err != nil {
2023-05-29 18:19:31 -04:00
return rowsInserted , err
2023-03-06 14:01:18 -05:00
}
2023-05-29 18:19:31 -04:00
return rowsInserted , nil
}
2024-06-06 01:40:56 -04:00
func ( d * DataClient ) InsertProgrammes ( programmes [ ] Programme ) ( int64 , error ) {
2023-05-29 18:19:31 -04:00
var rowsInserted int64
tx , err := d . DB . Beginx ( )
2023-03-06 14:01:18 -05:00
if err != nil {
2023-05-29 18:19:31 -04:00
return rowsInserted , err
2023-03-06 14:01:18 -05:00
}
2024-02-14 14:13:01 -05:00
defer tx . Rollback ( )
2023-03-06 14:01:18 -05:00
2023-05-29 18:19:31 -04:00
for _ , programme := range programmes {
if programme . ID == "" {
return 0 , errors . New ( "Cannot insert programme with no programme_id" )
}
2023-09-05 18:03:28 -04:00
result , err := tx . NamedExec ( "INSERT INTO programmes (id, titre) VALUES (:id, :titre) ON CONFLICT DO NOTHING;" , & programme )
2023-05-29 18:19:31 -04:00
if err != nil {
return 0 , err
}
rows , err := result . RowsAffected ( )
if err != nil {
return 0 , err
}
rowsInserted += rows
}
err = tx . Commit ( )
if err != nil {
return rowsInserted , err
}
return rowsInserted , nil
2023-03-06 14:01:18 -05:00
}
2024-06-06 01:40:56 -04:00
func ( d * DataClient ) GetMembre ( membreID string ) ( Membre , error ) {
var membre Membre
2023-05-29 18:19:31 -04:00
rows , err := d . DB . Queryx ( "SELECT * FROM membres WHERE id = $1 LIMIT 1;" , membreID )
if err != nil {
return membre , err
}
for rows . Next ( ) {
err := rows . StructScan ( & membre )
if err != nil {
return membre , err
}
}
if membre . ID == "" {
return membre , fmt . Errorf ( "No membre by that id was found" )
}
return membre , nil
2023-03-06 14:01:18 -05:00
}
2023-05-29 18:19:31 -04:00
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 )
if err != nil {
return 0 , err
}
rows , err := result . RowsAffected ( )
if err != nil {
return rows , err
}
return rows , nil
2023-03-06 14:01:18 -05:00
}
2023-09-19 19:09:51 -04:00
2024-06-06 01:40:56 -04:00
func ( d * DataClient ) GetMembres ( ) ( membres [ ] Membre , err error ) {
2023-09-19 19:09:51 -04:00
return membres , d . DB . Select ( & membres , "SELECT * FROM membres;" )
}
2024-06-06 01:40:56 -04:00
* /