2023-03-06 14:01:18 -05:00
package data
import (
"errors"
2023-05-29 18:19:31 -04:00
"fmt"
2023-03-06 14:01:18 -05:00
2024-01-05 14:38:48 -05:00
"git.agecem.com/agecem/bottin/v6/models"
2023-05-29 18:19:31 -04:00
_ "github.com/jackc/pgx/stdlib"
"github.com/jmoiron/sqlx"
2023-06-02 02:44:11 -04:00
"github.com/spf13/viper"
2023-03-06 14:01:18 -05:00
)
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 {
User : viper . GetString ( "db.user" ) ,
Password : viper . GetString ( "db.password" ) ,
Host : viper . GetString ( "db.host" ) ,
Database : viper . GetString ( "db.database" ) ,
Port : viper . GetInt ( "db.port" ) ,
} )
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 ) {
result , err := d . DB . Exec ( models . Schema )
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
func ( d * DataClient ) InsertMembres ( membres [ ] models . Membre ) ( int64 , error ) {
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
}
func ( d * DataClient ) InsertProgrammes ( programmes [ ] models . Programme ) ( int64 , error ) {
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
}
2023-05-29 18:19:31 -04:00
func ( d * DataClient ) GetMembre ( membreID string ) ( models . Membre , error ) {
var membre models . Membre
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
func ( d * DataClient ) GetMembres ( ) ( membres [ ] models . Membre , err error ) {
return membres , d . DB . Select ( & membres , "SELECT * FROM membres;" )
}