Skip to content

Commit

Permalink
Adds repository interface + MySQL implementation + tests. Closes #3
Browse files Browse the repository at this point in the history
  • Loading branch information
ariel17 committed Mar 7, 2023
1 parent 6216b58 commit ce030ef
Show file tree
Hide file tree
Showing 6 changed files with 571 additions and 6 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module github.com/ariel17/be-challenge-arios
go 1.17

require (
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/gin-gonic/gin v1.7.7
github.com/go-sql-driver/mysql v1.6.0
github.com/stretchr/testify v1.7.0
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2
github.com/swaggo/gin-swagger v1.4.1
Expand All @@ -26,7 +28,6 @@ require (
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
Expand Down
9 changes: 4 additions & 5 deletions init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ CREATE TABLE `teams` (
CREATE TABLE `teams_persons` (
`team_tla` CHAR(3),
`person_id` INT unsigned,
`position` VARCHAR(20),
`position` VARCHAR(20) NULL,
CONSTRAINT uc_person_by_team UNIQUE (`team_tla`, `person_id`),
FOREIGN KEY (`team_tla`) REFERENCES teams (`tla`),
FOREIGN KEY (`person_id`) REFERENCES persons (`id`)
Expand All @@ -31,14 +31,13 @@ CREATE TABLE `competitions` (
`code` CHAR(4),
`name` VARCHAR(50),
`area_name` VARCHAR(50),
`address` VARCHAR(200),
PRIMARY KEY (`code`)
);

CREATE TABLE `competitions_teams` (
`code` CHAR(4),
`competition_code` CHAR(4),
`team_tla` CHAR(3),
CONSTRAINT uc_team_by_competition UNIQUE (`code`, `team_tla`),
FOREIGN KEY (`code`) REFERENCES competitions (`code`),
CONSTRAINT uc_team_by_competition UNIQUE (`competition_code`, `team_tla`),
FOREIGN KEY (`competition_code`) REFERENCES competitions (`code`),
FOREIGN KEY (`team_tla`) REFERENCES teams (`tla`)
);
147 changes: 147 additions & 0 deletions pkg/repositories/mysql_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package repositories

import (
"database/sql"

_ "github.com/go-sql-driver/mysql"

"github.com/ariel17/be-challenge-arios/pkg/models"
)

func NewMySQLRepository() Repository {
return &mysqlRepository{}
}

type mysqlRepository struct {
db *sql.DB
}

func (m *mysqlRepository) Connect(dsn string) error {
db, err := sql.Open("mysql", dsn)
if err != nil {
return err
}
m.db = db
return nil
}

func (m *mysqlRepository) Close() error {
if m.db != nil {
return m.db.Close()
}
return nil
}

func (m *mysqlRepository) AddPerson(person models.Person) error {
query := "INSERT INTO `persons` (`id`, `name`, `date_of_birth`, `nationality`) VALUES (?, ?, ?, ?)"
_, err := m.db.Exec(query, person.ID, person.Name, person.DateOfBirth, person.Nationality)
return err
}

func (m *mysqlRepository) AddTeam(team models.Team) error {
query := "INSERT INTO `teams` (`tla`, `name`, `short_name`, `area_name`, `address`) VALUES (?, ?, ?, ?, ?)"
_, err := m.db.Exec(query, team.TLA, team.Name, team.ShortName, team.AreaName, team.Address)
return err
}

func (m *mysqlRepository) AddCompetition(competition models.Competition) error {
query := "INSERT INTO `competitions` (`code`, `name`, `area_name`) VALUES (?, ?, ?)"
_, err := m.db.Exec(query, competition.Code, competition.Name, competition.AreaName)
return err
}

func (m *mysqlRepository) AddTeamToCompetition(team models.Team, competition models.Competition) error {
query := "INSERT INTO `competitions_teams` (`competition_code`, `team_tla`) VALUES (?, ?)"
_, err := m.db.Exec(query, competition.Code, team.TLA)
return err
}

func (m *mysqlRepository) AddPersonToTeam(person models.Person, team models.Team) error {
query := "INSERT INTO `teams_persons` (`team_tla`, `person_id`, `position`) VALUES (?, ?, ?)"
_, err := m.db.Exec(query, team.TLA, person.ID, person.Position)
return err
}

func (m *mysqlRepository) GetTeamByTLA(tla string) (*models.Team, error) {
query := "SELECT `name`, `short_name`, `area_name`, `address` FROM `teams` WHERE `tla` = ?"
result, err := m.db.Query(query, tla)
if err != nil {
return nil, err
}

defer result.Close()
if !result.Next() {
return nil, nil
}

team := models.Team{TLA: tla}
err = result.Scan(&team.Name, &team.ShortName, &team.AreaName, &team.Address)
if err != nil {
return nil, err
}
return &team, nil
}

func (m *mysqlRepository) GetPersonsByCompetitionCode(code string) ([]models.Person, error) {
query := "SELECT p.id, p.name, p.date_of_birth, p.nationality, tp.position " +
"FROM competitions c " +
"INNER JOIN competitions_teams ct ON (c.code=ct.competition_code) " +
"INNER JOIN teams t ON (ct.team_tla=t.tla) " +
"INNER JOIN teams_persons tp ON (t.tla=tp.team_tla) " +
"INNER JOIN persons p ON (tp.person_id=p.id) " +
"WHERE c.code = ?"
result, err := m.db.Query(query, code)
if err != nil {
return nil, err
}

defer result.Close()
persons := []models.Person{}
for result.Next() {
var (
position sql.NullString
person models.Person
)
err = result.Scan(&person.ID, &person.Name, &person.DateOfBirth, &person.Nationality, &position)
if err != nil {
return nil, err
}
if position.Valid {
person.Position = &position.String
}
persons = append(persons, person)
}

return persons, nil
}

func (m *mysqlRepository) GetPersonsByTeamTLA(tla string) ([]models.Person, error) {
query := "SELECT p.id, p.name, p.date_of_birth, p.nationality, tp.position " +
"FROM teams t " +
"INNER JOIN teams_persons tp ON (t.tla=tp.team_tla) " +
"INNER JOIN persons p ON (tp.person_id=p.id) " +
"WHERE t.tla = ?"
result, err := m.db.Query(query, tla)
if err != nil {
return nil, err
}

defer result.Close()
persons := []models.Person{}
for result.Next() {
var (
position sql.NullString
person models.Person
)
err = result.Scan(&person.ID, &person.Name, &person.DateOfBirth, &person.Nationality, &position)
if err != nil {
return nil, err
}
if position.Valid {
person.Position = &position.String
}
persons = append(persons, person)
}

return persons, nil
}

0 comments on commit ce030ef

Please sign in to comment.