initial commit

This commit is contained in:
Laurent Le Houerou 2024-03-21 05:34:38 +00:00
commit 93af6e9c08
24 changed files with 1926 additions and 0 deletions

19
.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum

217
cmd/common/init.go Normal file
View File

@ -0,0 +1,217 @@
package common
import (
"context"
"fmt"
"os"
"strings"
"time"
"git.lehouerou.net/laurent/sorare"
"git.lehouerou.net/laurent/sorare/graphql"
"github.com/jackc/pgx/v5"
"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"git.lehouerou.net/laurent/sorarebuddy/model"
)
func InitParams(cmd *cobra.Command) {
cobra.OnInitialize(InitLog)
viper.AutomaticEnv()
viper.SetEnvPrefix("sorare")
cmd.PersistentFlags().BoolP("verbose", "v", false, "Verbose output")
_ = viper.BindPFlag("verbose", cmd.PersistentFlags().Lookup("verbose"))
viper.SetDefault("verbose", false)
cmd.PersistentFlags().String("jwttoken", "", "Sorare JWT Token")
_ = viper.BindPFlag("jwttoken", cmd.PersistentFlags().Lookup("jwttoken"))
viper.SetDefault("jwttoken", "")
cmd.PersistentFlags().String("jwtaudience", "", "Sorare JWT Audience")
_ = viper.BindPFlag("jwtaudience", cmd.PersistentFlags().Lookup("jwtaudience"))
viper.SetDefault("jwtaudience", "")
cmd.PersistentFlags().String("email", "", "Sorare Email")
_ = viper.BindPFlag("email", cmd.PersistentFlags().Lookup("email"))
viper.SetDefault("email", "")
cmd.PersistentFlags().String("password", "", "Sorare Password")
_ = viper.BindPFlag("password", cmd.PersistentFlags().Lookup("password"))
viper.SetDefault("password", "")
cmd.PersistentFlags().String("otp", "", "Sorare OTP")
_ = viper.BindPFlag("otp", cmd.PersistentFlags().Lookup("otp"))
viper.SetDefault("otp", "")
cmd.PersistentFlags().String("dbhost", "", "Database Host")
_ = viper.BindPFlag("dbhost", cmd.PersistentFlags().Lookup("dbhost"))
viper.SetDefault("dbhost", "192.168.1.250")
cmd.PersistentFlags().String("dbport", "", "Database Port")
_ = viper.BindPFlag("dbport", cmd.PersistentFlags().Lookup("dbport"))
viper.SetDefault("dbport", "5436")
cmd.PersistentFlags().String("dbuser", "", "Database User")
_ = viper.BindPFlag("dbuser", cmd.PersistentFlags().Lookup("dbuser"))
viper.SetDefault("dbuser", "sorare")
cmd.PersistentFlags().String("dbpass", "", "Database Password")
_ = viper.BindPFlag("dbpass", cmd.PersistentFlags().Lookup("dbpass"))
viper.SetDefault("dbpass", "sorare")
cmd.PersistentFlags().String("dbname", "", "Database Name")
_ = viper.BindPFlag("dbname", cmd.PersistentFlags().Lookup("dbname"))
viper.SetDefault("dbname", "sorare")
cmd.PersistentFlags().String("privatekey", "", "Sorare Private Key")
_ = viper.BindPFlag("privatekey", cmd.PersistentFlags().Lookup("privatekey"))
viper.SetDefault("privatekey", "")
cmd.PersistentFlags().Bool("tracedb", false, "Trace Database Queries")
_ = viper.BindPFlag("tracedb", cmd.PersistentFlags().Lookup("tracedb"))
viper.SetDefault("tracedb", false)
cmd.PersistentFlags().Bool("tracesorare", false, "Trace Sorare API Calls")
_ = viper.BindPFlag("tracesorare", cmd.PersistentFlags().Lookup("tracesorare"))
viper.SetDefault("tracesorare", false)
cmd.PersistentFlags().String("cryptkey", "", "Crypt Key")
_ = viper.BindPFlag("cryptkey", cmd.PersistentFlags().Lookup("cryptkey"))
viper.SetDefault("cryptkey", "")
cmd.PersistentFlags().String("jwtkey", "", "JWT Key")
_ = viper.BindPFlag("jwtkey", cmd.PersistentFlags().Lookup("jwtkey"))
viper.SetDefault("jwtkey", "")
}
func InitLog() {
log.Logger = zerolog.New(zerolog.ConsoleWriter{
Out: os.Stdout,
TimeFormat: "2006-01-02 | 15:04:05.000",
FormatLevel: func(i interface{}) string {
return strings.ToUpper(fmt.Sprintf("| %-6s|", i))
},
FormatFieldName: func(i interface{}) string {
return fmt.Sprintf("%s:", i)
},
FormatFieldValue: func(i interface{}) string {
return strings.ToUpper(fmt.Sprintf("%s", i))
},
}).With().Timestamp().Logger()
zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMicro
zerolog.SetGlobalLevel(zerolog.InfoLevel)
verbose := viper.GetBool("verbose")
if verbose {
log.Info().Msg("Verbose output enabled")
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
}
func InitSorare(ctx context.Context) (*sorare.Sorare, error) {
audience := viper.GetString("jwtaudience")
if audience == "" {
return nil, errors.New("jwtaudience is required")
}
jwttoken := viper.GetString("jwttoken")
s := sorare.New()
tracesorare := viper.GetBool("tracesorare")
if tracesorare {
s.Debug()
}
if jwttoken != "" {
s.SetJWTToken(graphql.JwtToken{
Token: jwttoken,
ExpiredAt: time.Time{},
}, audience)
} else {
email := viper.GetString("email")
password := viper.GetString("password")
otp := viper.GetString("otp")
err := s.Authenticate(ctx, email, password, audience, otp)
if err != nil {
return nil, errors.Wrap(err, "authenticating to sorare")
}
log.Info().Msgf("authentication to sorare successful. new token: %s", s.GetCurrentToken().Token)
}
cu, err := s.Users.CurrentUser.Get(ctx, graphql.EmptyParams{})
if err != nil {
return nil, errors.Wrap(err, "getting current user")
}
log.Info().Msgf("authenticated on Sorare as %s (%s)", cu.Nickname, cu.Profile.ClubName)
return s, nil
}
func InitDb(ctx context.Context) (*model.Queries, error) {
host := viper.GetString("dbhost")
if host == "" {
return nil, errors.New("dbhost is required")
}
port := viper.GetString("dbport")
if port == "" {
return nil, errors.New("dbport is required")
}
user := viper.GetString("dbuser")
if user == "" {
return nil, errors.New("dbuser is required")
}
password := viper.GetString("dbpass")
if password == "" {
return nil, errors.New("dbpass is required")
}
dbname := viper.GetString("dbname")
if dbname == "" {
return nil, errors.New("dbname is required")
}
conn, err := pgx.Connect(
ctx,
fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
host,
port,
user,
password,
dbname,
),
)
if err != nil {
return nil, errors.Wrap(err, "connecting to database")
}
queries := model.New(conn)
log.Info().Msgf("connected to database %s@%s:%s/%s", user, host, port, dbname)
return queries, nil
}
type contextKey string
const (
SorareContextKey contextKey = "sorare"
DbContextKey contextKey = "db"
)
func CmdPreRunE(cmd *cobra.Command, _ []string) error {
s, err := InitSorare(cmd.Context())
if err != nil {
return errors.Wrap(err, "initializing sorare client")
}
cmd.SetContext(context.WithValue(cmd.Context(), SorareContextKey, s))
db, err := InitDb(cmd.Context())
if err != nil {
return errors.Wrap(err, "initializing database")
}
cmd.SetContext(context.WithValue(cmd.Context(), DbContextKey, db))
return nil
}

47
cmd/common/main.go Normal file
View File

@ -0,0 +1,47 @@
package common
import (
"context"
"os"
"os/signal"
"syscall"
"time"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
func Start(cmd *cobra.Command) {
ctx, cancel := context.WithCancel(context.Background())
returnCode := make(chan int)
terminated := make(chan interface{})
go trapSignals(cancel, terminated, returnCode)
if err := cmd.ExecuteContext(ctx); err != nil {
log.Error().Err(err).Send()
sendReturnCode(returnCode, -2)
} else {
sendReturnCode(returnCode, 0)
}
close(terminated)
os.Exit(<-returnCode)
}
func sendReturnCode(returnCode chan<- int, code int) {
go func(returnCode chan<- int) { returnCode <- code }(returnCode)
}
func trapSignals(cancel context.CancelFunc, terminated chan interface{}, returnCode chan int) {
stopSignal := make(chan os.Signal, 1)
signal.Notify(stopSignal, syscall.SIGTERM, syscall.SIGINT)
<-stopSignal
log.Info().Msg("received stop signal. shutting down...")
cancel()
select {
case <-time.After(30 * time.Second):
log.Warn().Msg("app shutdown sequence timed out")
returnCode <- 1
case <-terminated:
returnCode <- 0
}
}

281
cmd/console/root.go Normal file
View File

@ -0,0 +1,281 @@
package main
import (
"git.lehouerou.net/laurent/sorare"
"git.lehouerou.net/laurent/sorare/football"
"git.lehouerou.net/laurent/sorare/graphql"
"github.com/jackc/pgx/v5/pgtype"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"github.com/spf13/cobra"
"git.lehouerou.net/laurent/sorarebuddy/cmd/common"
"git.lehouerou.net/laurent/sorarebuddy/model"
)
var Cmd = &cobra.Command{
Use: "console",
Short: "console",
Long: `console`,
RunE: run,
PersistentPreRunE: common.CmdPreRunE,
}
func main() {
common.Start(Cmd)
}
func init() {
common.InitParams(Cmd)
}
func run(cmd *cobra.Command, _ []string) error {
//var wg conc.WaitGroup
ctx := cmd.Context()
s, ok := ctx.Value(common.SorareContextKey).(*sorare.Sorare)
if !ok {
return errors.New("sorare not found in context")
}
db, ok := ctx.Value(common.DbContextKey).(*model.Queries)
if !ok {
return errors.New("db not found in context")
}
sfixtures, err := s.Football.So5.So5Fixtures.Get(ctx, football.So5FixturesParams{})
if err != nil {
return err
}
log.Debug().Msgf("fixtures: %v", sfixtures)
cnt, err := db.CreateFixtures(
ctx,
lo.Map(sfixtures, func(fixture football.So5Fixture, index int) model.CreateFixturesParams {
return model.CreateFixturesParams{
Slug: fixture.Slug,
DisplayName: fixture.DisplayName,
State: fixture.AasmState,
StartDate: pgtype.Timestamptz{Time: fixture.StartDate, Valid: true},
EndDate: pgtype.Timestamptz{Time: fixture.EndDate, Valid: true},
GameWeek: int32(fixture.GameWeek),
}
}),
)
if err != nil {
return err
}
log.Debug().Msgf("created %d fixtures", cnt)
fixtures, err := db.GetAllFixtures(ctx)
if err != nil {
return err
}
var games []football.Game
for _, fixture := range fixtures {
log.Debug().Msgf("fixture: %v", fixture)
g, err := s.Football.So5.FixtureGames(fixture.Slug).Get(ctx, graphql.EmptyParams{})
if err != nil {
return err
}
log.Debug().Msgf("games: %d", len(g))
games = append(games, g...)
}
log.Debug().Msgf("games: %d", len(games))
var teamSlugs []string
teamSlugs = lo.Map(games, func(game football.Game, index int) string {
return game.AwayTeam.Team.Slug
})
teamSlugs = append(teamSlugs, lo.Map(games, func(game football.Game, index int) string {
return game.HomeTeam.Team.Slug
})...)
teamSlugs = lo.Filter(teamSlugs, func(slug string, index int) bool {
return slug != ""
})
teamSlugs = lo.Uniq(teamSlugs)
var clubs []football.Club
for _, chunk := range lo.Chunk(teamSlugs, 100) {
t, err := s.Football.Clubs.Get(ctx, graphql.SlugsParams{Slugs: chunk})
if err != nil {
return err
}
clubs = append(clubs, t...)
}
var nationalTeams []football.NationalTeam
for _, chunk := range lo.Chunk(lo.Without(teamSlugs, lo.Map(clubs, func(club football.Club, index int) string {
return club.Slug
})...), 100) {
t, err := s.Football.NationalTeams.Get(ctx, graphql.SlugsParams{Slugs: chunk})
if err != nil {
return err
}
nationalTeams = append(nationalTeams, t...)
}
var teamsToInsert []model.CreateTeamsParams
teamsToInsert = append(teamsToInsert, lo.Map(clubs, func(club football.Club, index int) model.CreateTeamsParams {
return model.CreateTeamsParams{
Slug: club.Slug,
DisplayName: club.Name,
CountrySlug: club.Country.Slug,
DomesticLeagueSlug: func() *string {
if club.DomesticLeague.Slug == "" {
return nil
}
return &club.DomesticLeague.Slug
}(),
ShortName: club.ShortName,
PictureUrl: club.PictureUrl,
TeamType: "club",
}
})...)
teamsToInsert = append(
teamsToInsert,
lo.Map(nationalTeams, func(nationalTeam football.NationalTeam, index int) model.CreateTeamsParams {
return model.CreateTeamsParams{
Slug: nationalTeam.Slug,
DisplayName: nationalTeam.Name,
CountrySlug: nationalTeam.Country.Slug,
DomesticLeagueSlug: nil,
ShortName: nationalTeam.ShortName,
PictureUrl: nationalTeam.PictureUrl,
TeamType: "national",
}
})...)
competitionSlugs := lo.Map(games, func(game football.Game, index int) string {
return game.Competition.Slug
})
competitionSlugs = append(
competitionSlugs,
lo.Map(teamsToInsert, func(team model.CreateTeamsParams, index int) string {
if team.DomesticLeagueSlug == nil {
return ""
}
return *team.DomesticLeagueSlug
})...)
competitionSlugs = lo.Filter(competitionSlugs, func(slug string, index int) bool {
return slug != ""
})
competitionSlugs = lo.Uniq(competitionSlugs)
var competitions []football.Competition
for _, slug := range competitionSlugs {
log.Debug().Msgf("competition: %s", slug)
c, err := s.Football.Competition.Get(ctx, graphql.SlugParams{Slug: slug})
if err != nil {
return err
}
competitions = append(competitions, c)
}
var countrySlugs []string
countrySlugs = append(countrySlugs, lo.Map(teamsToInsert, func(team model.CreateTeamsParams, index int) string {
return team.CountrySlug
})...)
countrySlugs = append(countrySlugs, lo.Map(competitions, func(competition football.Competition, index int) string {
return competition.Country.Slug
})...)
countrySlugs = lo.Filter(countrySlugs, func(slug string, index int) bool {
return slug != ""
})
countrySlugs = lo.Uniq(countrySlugs)
var countries []sorare.Country
for _, chunk := range lo.Chunk(countrySlugs, 100) {
c, err := s.Countries.Get(ctx, graphql.SlugsParams{Slugs: chunk})
if err != nil {
return err
}
countries = append(countries, c...)
}
cnt, err = db.CreateCountries(
ctx,
lo.Map(countries, func(country sorare.Country, index int) model.CreateCountriesParams {
return model.CreateCountriesParams{
Slug: country.Slug,
Code: country.Code,
DisplayName: country.Name,
ThreeLetterCode: country.ThreeLetterCode,
FlagFlat64Url: country.FlagFlat64Url,
FlagFlat32Url: country.FlagFlat32Url,
FlagRound64Url: country.FlagRound64Url,
FlagRound32Url: country.FlagRound32Url,
}
}),
)
if err != nil {
return err
}
log.Debug().Msgf("created %d countries", cnt)
log.Debug().Msgf("competitions: %d", len(competitions))
for _, competition := range competitions {
err := db.CreateOrUpdateCompetition(ctx, model.CreateOrUpdateCompetitionParams{
Slug: competition.Slug,
CompetitionFormat: competition.Format,
CompetitionType: competition.Type,
DisplayName: competition.DisplayName,
PictureUrl: competition.PictureUrl,
LogoUrl: competition.LogoUrl,
CountrySlug: competition.Country.Slug,
})
if err != nil {
return err
}
}
cnt, err = db.CreateTeams(ctx, teamsToInsert)
if err != nil {
return err
}
log.Debug().Msgf("created %d teams", cnt)
cnt, err = db.CreateGames(ctx, lo.Map(games, func(game football.Game, index int) model.CreateGamesParams {
return model.CreateGamesParams{
CoverageStatus: game.CoverageStatus,
LowCoverage: game.LowCoverage,
Minutes: int32(game.Minute),
PeriodType: game.PeriodType,
Scored: game.Scored,
Status: game.Status,
CompetitionSlug: game.Competition.Slug,
FixtureSlug: game.So5Fixture.Slug,
AwayTeamSlug: game.AwayTeam.Team.Slug,
AwayGoals: int32(game.AwayGoals),
AwayExtraTimeScore: int32(game.ExtraTimeScoreAway),
AwayPenaltyScore: int32(game.PenaltyScoreAway),
HomeTeamSlug: game.HomeTeam.Team.Slug,
HomeGoals: int32(game.HomeGoals),
HomeExtraTimeScore: int32(game.ExtraTimeScoreHome),
HomePenaltyScore: int32(game.PenaltyScoreHome),
WinnerTeamSlug: func() *string {
if game.Winner.Team.Slug == "" {
return nil
}
return &game.Winner.Team.Slug
}(),
}
}))
if err != nil {
return err
}
log.Debug().Msgf("created %d games", cnt)
// log.Debug().Msg("start sequence completed. waiting for shutdown request")
// <-ctx.Done()
// log.Debug().Msg("shutdown requested")
// wg.Wait()
// log.Debug().Msg("shutdown complete")
return nil
}

View File

@ -0,0 +1,205 @@
-- +goose Up
BEGIN;
CREATE TABLE IF NOT EXISTS zones (id SERIAL PRIMARY KEY, display_name TEXT NOT NULL);
INSERT INTO zones (display_name)
VALUES ('Champions');
INSERT INTO zones (display_name)
VALUES ('Contenders');
INSERT INTO zones (display_name)
VALUES ('Challengers');
CREATE TABLE IF NOT EXISTS countries (
slug TEXT PRIMARY KEY,
code TEXT NOT NULL,
display_name TEXT NOT NULL,
three_letter_code TEXT NOT NULL,
flag_flat_64_url TEXT NOT NULL,
flag_flat_32_url TEXT NOT NULL,
flag_round_64_url TEXT NOT NULL,
flag_round_32_url TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS competitions (
slug TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
country_slug TEXT NOT NULL,
FOREIGN KEY (country_slug) REFERENCES countries (slug),
competition_format TEXT NOT NULL,
competition_type TEXT NOT NULL,
picture_url TEXT NOT NULL,
logo_url TEXT NOT NULL,
zone_id INTEGER,
FOREIGN KEY (zone_id) REFERENCES zones (id)
);
CREATE TABLE IF NOT EXISTS fixtures (
slug TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
state TEXT NOT NULL,
start_date TIMESTAMPTZ NOT NULL,
end_date TIMESTAMPTZ NOT NULL,
game_week INTEGER NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS teams (
slug TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
country_slug TEXT NOT NULL,
FOREIGN KEY (country_slug) REFERENCES countries (slug),
domestic_league_slug TEXT,
FOREIGN KEY (domestic_league_slug) REFERENCES competitions (slug),
short_name TEXT NOT NULL,
picture_url TEXT NOT NULL,
team_type TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS games (
id TEXT PRIMARY KEY,
date TIMESTAMPTZ,
coverage_status TEXT NOT NULL,
low_coverage BOOLEAN NOT NULL,
minutes INTEGER NOT NULL,
period_type TEXT NOT NULL,
scored BOOLEAN NOT NULL,
status TEXT NOT NULL,
competition_slug TEXT NOT NULL,
FOREIGN KEY (competition_slug) REFERENCES competitions (slug),
fixture_slug TEXT NOT NULL,
FOREIGN KEY (fixture_slug) REFERENCES fixtures (slug),
away_team_slug TEXT NOT NULL,
FOREIGN KEY (away_team_slug) REFERENCES teams (slug),
away_goals INTEGER NOT NULL,
away_extra_time_score INTEGER NOT NULL,
away_penalty_score INTEGER NOT NULL,
home_team_slug TEXT NOT NULL,
FOREIGN KEY (home_team_slug) REFERENCES teams (slug),
home_goals INTEGER NOT NULL,
home_extra_time_score INTEGER NOT NULL,
home_penalty_score INTEGER NOT NULL,
winner_team_slug TEXT,
FOREIGN KEY (winner_team_slug) REFERENCES teams (slug)
);
CREATE TABLE IF NOT EXISTS players (
slug TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
birth_date DATE NOT NULL,
country_slug TEXT NOT NULL,
FOREIGN KEY (country_slug) REFERENCES countries (slug),
team_slug TEXT NOT NULL,
FOREIGN KEY (team_slug) REFERENCES teams (slug),
domestic_league_slug TEXT NOT NULL,
FOREIGN KEY (domestic_league_slug) REFERENCES competitions (slug),
avatar_url TEXT NOT NULL,
field_position TEXT NOT NULL,
status TEXT NOT NULL,
shirt_number INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS game_players (
game_id TEXT NOT NULL,
FOREIGN KEY (game_id) REFERENCES games (id),
player_slug TEXT NOT NULL,
FOREIGN KEY (player_slug) REFERENCES players (slug),
status TEXT NOT NULL,
team_slug TEXT NOT NULL,
FOREIGN KEY (team_slug) REFERENCES teams (slug),
PRIMARY KEY (game_id, player_slug)
);
CREATE INDEX idx_game_players_game_id_team_slug ON game_players (game_id, team_slug);
CREATE TABLE IF NOT EXISTS game_player_scores (
game_id TEXT NOT NULL,
FOREIGN KEY (game_id) REFERENCES games (id),
player_slug TEXT NOT NULL,
FOREIGN KEY (player_slug) REFERENCES players (slug),
FOREIGN KEY (game_id, player_slug) REFERENCES game_players (game_id, player_slug),
PRIMARY KEY (game_id, player_slug),
score NUMERIC NOT NULL,
decisive_score NUMERIC NOT NULL,
all_around_score NUMERIC NOT NULL,
minutes_played INTEGER NOT NULL,
game_started BOOLEAN NOT NULL,
formation_place INTEGER NOT NULL,
live BOOLEAN NOT NULL,
on_game_sheet BOOLEAN NOT NULL,
reviewed BOOLEAN NOT NULL,
goal INTEGER NOT NULL,
assist INTEGER NOT NULL,
penalty_won INTEGER NOT NULL,
clearance_off_line INTEGER NOT NULL,
last_man_tackle INTEGER NOT NULL,
penalty_save INTEGER NOT NULL,
own_goal INTEGER NOT NULL,
red_card BOOLEAN NOT NULL,
error_lead_to_goal INTEGER NOT NULL,
penalty_conceded INTEGER NOT NULL,
yellow_card INTEGER NOT NULL,
fouls INTEGER NOT NULL,
fouled INTEGER NOT NULL,
clean_sheet BOOLEAN NOT NULL,
double_double BOOLEAN NOT NULL,
triple_double BOOLEAN NOT NULL,
triple_triple BOOLEAN NOT NULL,
error_lead_to_shot INTEGER NOT NULL,
saves INTEGER NOT NULL,
saved_shot_from_inside_box INTEGER NOT NULL,
good_high_claim INTEGER NOT NULL,
punches INTEGER NOT NULL,
diving_save INTEGER NOT NULL,
diving_catch INTEGER NOT NULL,
cross_not_claimed INTEGER NOT NULL,
goalkeeper_smother INTEGER NOT NULL,
six_second_violation INTEGER NOT NULL,
keeper_sweeper INTEGER NOT NULL,
goals_conceded INTEGER NOT NULL,
effective_clearance INTEGER NOT NULL,
won_tackle INTEGER NOT NULL,
blocked_cross INTEGER NOT NULL,
block INTEGER NOT NULL,
possession_lost INTEGER NOT NULL,
possession_won INTEGER NOT NULL,
duel_lost INTEGER NOT NULL,
duel_won INTEGER NOT NULL,
interception INTEGER NOT NULL,
accurate_pass INTEGER NOT NULL,
accurate_final_third_pass INTEGER NOT NULL,
accurate_long_ball INTEGER NOT NULL,
long_pass_into_opposition INTEGER NOT NULL,
missed_pass INTEGER NOT NULL,
shot_on_target INTEGER NOT NULL,
won_contest INTEGER NOT NULL,
big_chance_created INTEGER NOT NULL,
attempted_assist INTEGER NOT NULL,
penalty_area_entries INTEGER NOT NULL,
penalty_kick_missed INTEGER NOT NULL,
big_chance_missed INTEGER NOT NULL
);
COMMIT;
-- +goose Down
DROP TABLE IF EXISTS game_player_scores;
DROP INDEX IF EXISTS idx_game_players_game_id_team_slug;
DROP TABLE IF EXISTS game_players;
DROP TABLE IF EXISTS players;
DROP TABLE IF EXISTS games;
DROP TABLE IF EXISTS teams;
DROP TABLE IF EXISTS fixtures;
DROP TABLE IF EXISTS competitions;
DROP TABLE IF EXISTS countries;
DROP TABLE IF EXISTS zones;

55
go.mod Normal file
View File

@ -0,0 +1,55 @@
module git.lehouerou.net/laurent/sorarebuddy
go 1.22.1
require (
github.com/jackc/pgx/v5 v5.5.5
github.com/shopspring/decimal v1.3.1
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.2
)
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/llehouerou/go-graphql-client v0.9.6 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/xlzd/gotp v0.1.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/time v0.5.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)
require (
git.lehouerou.net/laurent/sorare v0.0.0-20240308104821-b99d85580526
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.32.0
github.com/samber/lo v1.39.0
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/text v0.14.0 // indirect
)

191
go.sum Normal file
View File

@ -0,0 +1,191 @@
git.lehouerou.net/laurent/sorare v0.0.0-20240308104821-b99d85580526 h1:/qgeHqVliEYKynyyDEnS45e6I8uS7bAFkw1ucpQ3D8I=
git.lehouerou.net/laurent/sorare v0.0.0-20240308104821-b99d85580526/go.mod h1:s/kVH8wu+esjAd1Zw+8+UGovg5hVClZp+9lFu7ZXsbI=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc=
github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os=
github.com/graph-gophers/graphql-transport-ws v0.0.2 h1:DbmSkbIGzj8SvHei6n8Mh9eLQin8PtA8xY9eCzjRpvo=
github.com/graph-gophers/graphql-transport-ws v0.0.2/go.mod h1:5BVKvFzOd2BalVIBFfnfmHjpJi/MZ5rOj8G55mXvZ8g=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/llehouerou/go-graphql-client v0.9.6 h1:tZdCHrBz8p044KoxXwmEur9L4VNZ3luYeJmQZpLodPY=
github.com/llehouerou/go-graphql-client v0.9.6/go.mod h1:hyvnfe3diGLxMelSKF+cFPyAfxZLa1CGGBogmix4SyM=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=

151
model/competition.sql.go Normal file
View File

@ -0,0 +1,151 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: competition.sql
package model
import (
"context"
)
const createOrUpdateCompetition = `-- name: CreateOrUpdateCompetition :exec
INSERT INTO competitions (
slug,
display_name,
country_slug,
competition_format,
competition_type,
picture_url,
logo_url
)
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (slug)
DO
UPDATE
SET display_name = EXCLUDED.display_name,
competition_format = EXCLUDED.competition_format,
competition_type = EXCLUDED.competition_type,
picture_url = EXCLUDED.picture_url,
logo_url = EXCLUDED.logo_url,
country_slug = EXCLUDED.country_slug
`
type CreateOrUpdateCompetitionParams struct {
Slug string
DisplayName string
CountrySlug string
CompetitionFormat string
CompetitionType string
PictureUrl string
LogoUrl string
}
// Active: 1709890109198@@192.168.1.250@5436@sorare
func (q *Queries) CreateOrUpdateCompetition(ctx context.Context, arg CreateOrUpdateCompetitionParams) error {
_, err := q.db.Exec(ctx, createOrUpdateCompetition,
arg.Slug,
arg.DisplayName,
arg.CountrySlug,
arg.CompetitionFormat,
arg.CompetitionType,
arg.PictureUrl,
arg.LogoUrl,
)
return err
}
const getAllCompetitions = `-- name: GetAllCompetitions :many
SELECT competitions.slug, competitions.display_name, competitions.country_slug, competitions.competition_format, competitions.competition_type, competitions.picture_url, competitions.logo_url, competitions.zone_id,
zones.id, zones.display_name,
countries.slug, countries.code, countries.display_name, countries.three_letter_code, countries.flag_flat_64_url, countries.flag_flat_32_url, countries.flag_round_64_url, countries.flag_round_32_url
FROM competitions
LEFT JOIN zones ON competitions.zone_id = zones.id
LEFT JOIN countries ON competitions.country_slug = countries.slug
`
type GetAllCompetitionsRow struct {
Competition Competition
Zone Zone
Country Country
}
func (q *Queries) GetAllCompetitions(ctx context.Context) ([]GetAllCompetitionsRow, error) {
rows, err := q.db.Query(ctx, getAllCompetitions)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAllCompetitionsRow
for rows.Next() {
var i GetAllCompetitionsRow
if err := rows.Scan(
&i.Competition.Slug,
&i.Competition.DisplayName,
&i.Competition.CountrySlug,
&i.Competition.CompetitionFormat,
&i.Competition.CompetitionType,
&i.Competition.PictureUrl,
&i.Competition.LogoUrl,
&i.Competition.ZoneID,
&i.Zone.ID,
&i.Zone.DisplayName,
&i.Country.Slug,
&i.Country.Code,
&i.Country.DisplayName,
&i.Country.ThreeLetterCode,
&i.Country.FlagFlat64Url,
&i.Country.FlagFlat32Url,
&i.Country.FlagRound64Url,
&i.Country.FlagRound32Url,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getCompetitionBySlug = `-- name: GetCompetitionBySlug :one
SELECT competitions.slug, competitions.display_name, competitions.country_slug, competitions.competition_format, competitions.competition_type, competitions.picture_url, competitions.logo_url, competitions.zone_id,
zones.id, zones.display_name,
countries.slug, countries.code, countries.display_name, countries.three_letter_code, countries.flag_flat_64_url, countries.flag_flat_32_url, countries.flag_round_64_url, countries.flag_round_32_url
FROM competitions
LEFT JOIN zones ON competitions.zone_id = zones.id
LEFT JOIN countries ON competitions.country_slug = countries.slug
WHERE competitions.slug = $1
`
type GetCompetitionBySlugRow struct {
Competition Competition
Zone Zone
Country Country
}
func (q *Queries) GetCompetitionBySlug(ctx context.Context, slug string) (GetCompetitionBySlugRow, error) {
row := q.db.QueryRow(ctx, getCompetitionBySlug, slug)
var i GetCompetitionBySlugRow
err := row.Scan(
&i.Competition.Slug,
&i.Competition.DisplayName,
&i.Competition.CountrySlug,
&i.Competition.CompetitionFormat,
&i.Competition.CompetitionType,
&i.Competition.PictureUrl,
&i.Competition.LogoUrl,
&i.Competition.ZoneID,
&i.Zone.ID,
&i.Zone.DisplayName,
&i.Country.Slug,
&i.Country.Code,
&i.Country.DisplayName,
&i.Country.ThreeLetterCode,
&i.Country.FlagFlat64Url,
&i.Country.FlagFlat32Url,
&i.Country.FlagRound64Url,
&i.Country.FlagRound32Url,
)
return i, err
}

175
model/copyfrom.go Normal file
View File

@ -0,0 +1,175 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: copyfrom.go
package model
import (
"context"
)
// iteratorForCreateCountries implements pgx.CopyFromSource.
type iteratorForCreateCountries struct {
rows []CreateCountriesParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateCountries) Next() bool {
if len(r.rows) == 0 {
return false
}
if !r.skippedFirstNextCall {
r.skippedFirstNextCall = true
return true
}
r.rows = r.rows[1:]
return len(r.rows) > 0
}
func (r iteratorForCreateCountries) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].Slug,
r.rows[0].Code,
r.rows[0].DisplayName,
r.rows[0].ThreeLetterCode,
r.rows[0].FlagFlat64Url,
r.rows[0].FlagFlat32Url,
r.rows[0].FlagRound64Url,
r.rows[0].FlagRound32Url,
}, nil
}
func (r iteratorForCreateCountries) Err() error {
return nil
}
func (q *Queries) CreateCountries(ctx context.Context, arg []CreateCountriesParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"countries"}, []string{"slug", "code", "display_name", "three_letter_code", "flag_flat_64_url", "flag_flat_32_url", "flag_round_64_url", "flag_round_32_url"}, &iteratorForCreateCountries{rows: arg})
}
// iteratorForCreateFixtures implements pgx.CopyFromSource.
type iteratorForCreateFixtures struct {
rows []CreateFixturesParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateFixtures) Next() bool {
if len(r.rows) == 0 {
return false
}
if !r.skippedFirstNextCall {
r.skippedFirstNextCall = true
return true
}
r.rows = r.rows[1:]
return len(r.rows) > 0
}
func (r iteratorForCreateFixtures) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].Slug,
r.rows[0].DisplayName,
r.rows[0].State,
r.rows[0].StartDate,
r.rows[0].EndDate,
r.rows[0].GameWeek,
}, nil
}
func (r iteratorForCreateFixtures) Err() error {
return nil
}
// Active: 1709890109198@@192.168.1.250@5436@sorare
func (q *Queries) CreateFixtures(ctx context.Context, arg []CreateFixturesParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"fixtures"}, []string{"slug", "display_name", "state", "start_date", "end_date", "game_week"}, &iteratorForCreateFixtures{rows: arg})
}
// iteratorForCreateGames implements pgx.CopyFromSource.
type iteratorForCreateGames struct {
rows []CreateGamesParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateGames) Next() bool {
if len(r.rows) == 0 {
return false
}
if !r.skippedFirstNextCall {
r.skippedFirstNextCall = true
return true
}
r.rows = r.rows[1:]
return len(r.rows) > 0
}
func (r iteratorForCreateGames) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].ID,
r.rows[0].Date,
r.rows[0].CoverageStatus,
r.rows[0].LowCoverage,
r.rows[0].Minutes,
r.rows[0].PeriodType,
r.rows[0].Scored,
r.rows[0].Status,
r.rows[0].CompetitionSlug,
r.rows[0].FixtureSlug,
r.rows[0].AwayTeamSlug,
r.rows[0].AwayGoals,
r.rows[0].AwayExtraTimeScore,
r.rows[0].AwayPenaltyScore,
r.rows[0].HomeTeamSlug,
r.rows[0].HomeGoals,
r.rows[0].HomeExtraTimeScore,
r.rows[0].HomePenaltyScore,
r.rows[0].WinnerTeamSlug,
}, nil
}
func (r iteratorForCreateGames) Err() error {
return nil
}
func (q *Queries) CreateGames(ctx context.Context, arg []CreateGamesParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"games"}, []string{"id", "date", "coverage_status", "low_coverage", "minutes", "period_type", "scored", "status", "competition_slug", "fixture_slug", "away_team_slug", "away_goals", "away_extra_time_score", "away_penalty_score", "home_team_slug", "home_goals", "home_extra_time_score", "home_penalty_score", "winner_team_slug"}, &iteratorForCreateGames{rows: arg})
}
// iteratorForCreateTeams implements pgx.CopyFromSource.
type iteratorForCreateTeams struct {
rows []CreateTeamsParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateTeams) Next() bool {
if len(r.rows) == 0 {
return false
}
if !r.skippedFirstNextCall {
r.skippedFirstNextCall = true
return true
}
r.rows = r.rows[1:]
return len(r.rows) > 0
}
func (r iteratorForCreateTeams) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].Slug,
r.rows[0].DisplayName,
r.rows[0].CountrySlug,
r.rows[0].DomesticLeagueSlug,
r.rows[0].ShortName,
r.rows[0].PictureUrl,
r.rows[0].TeamType,
}, nil
}
func (r iteratorForCreateTeams) Err() error {
return nil
}
func (q *Queries) CreateTeams(ctx context.Context, arg []CreateTeamsParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"teams"}, []string{"slug", "display_name", "country_slug", "domestic_league_slug", "short_name", "picture_url", "team_type"}, &iteratorForCreateTeams{rows: arg})
}

69
model/country.sql.go Normal file
View File

@ -0,0 +1,69 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: country.sql
package model
import (
"context"
)
type CreateCountriesParams struct {
Slug string
Code string
DisplayName string
ThreeLetterCode string
FlagFlat64Url string
FlagFlat32Url string
FlagRound64Url string
FlagRound32Url string
}
const createOrUpdateCountry = `-- name: CreateOrUpdateCountry :exec
INSERT INTO countries (
slug,
code,
display_name,
three_letter_code,
flag_flat_64_url,
flag_flat_32_url,
flag_round_64_url,
flag_round_32_url
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (slug)
DO
UPDATE
SET code = EXCLUDED.code,
display_name = EXCLUDED.display_name,
three_letter_code = EXCLUDED.three_letter_code,
flag_flat_64_url = EXCLUDED.flag_flat_64_url,
flag_flat_32_url = EXCLUDED.flag_flat_32_url,
flag_round_64_url = EXCLUDED.flag_round_64_url,
flag_round_32_url = EXCLUDED.flag_round_32_url
`
type CreateOrUpdateCountryParams struct {
Slug string
Code string
DisplayName string
ThreeLetterCode string
FlagFlat64Url string
FlagFlat32Url string
FlagRound64Url string
FlagRound32Url string
}
func (q *Queries) CreateOrUpdateCountry(ctx context.Context, arg CreateOrUpdateCountryParams) error {
_, err := q.db.Exec(ctx, createOrUpdateCountry,
arg.Slug,
arg.Code,
arg.DisplayName,
arg.ThreeLetterCode,
arg.FlagFlat64Url,
arg.FlagFlat32Url,
arg.FlagRound64Url,
arg.FlagRound32Url,
)
return err
}

33
model/db.go Normal file
View File

@ -0,0 +1,33 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
package model
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error)
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

116
model/fixture.sql.go Normal file
View File

@ -0,0 +1,116 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: fixture.sql
package model
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
type CreateFixturesParams struct {
Slug string
DisplayName string
State string
StartDate pgtype.Timestamptz
EndDate pgtype.Timestamptz
GameWeek int32
}
const createOrUpdateFixture = `-- name: CreateOrUpdateFixture :exec
INSERT INTO fixtures (slug, display_name, state, start_date, end_date, game_week)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (slug) DO UPDATE
SET display_name = $2, state = $3, start_date = $4, end_date = $5, game_week = $6
`
type CreateOrUpdateFixtureParams struct {
Slug string
DisplayName string
State string
StartDate pgtype.Timestamptz
EndDate pgtype.Timestamptz
GameWeek int32
}
func (q *Queries) CreateOrUpdateFixture(ctx context.Context, arg CreateOrUpdateFixtureParams) error {
_, err := q.db.Exec(ctx, createOrUpdateFixture,
arg.Slug,
arg.DisplayName,
arg.State,
arg.StartDate,
arg.EndDate,
arg.GameWeek,
)
return err
}
const getAllFixtures = `-- name: GetAllFixtures :many
SELECT slug, display_name, state, start_date, end_date, game_week FROM fixtures
`
func (q *Queries) GetAllFixtures(ctx context.Context) ([]Fixture, error) {
rows, err := q.db.Query(ctx, getAllFixtures)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Fixture
for rows.Next() {
var i Fixture
if err := rows.Scan(
&i.Slug,
&i.DisplayName,
&i.State,
&i.StartDate,
&i.EndDate,
&i.GameWeek,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFixtureByGameWeek = `-- name: GetFixtureByGameWeek :one
SELECT slug, display_name, state, start_date, end_date, game_week FROM fixtures WHERE game_week = $1
`
func (q *Queries) GetFixtureByGameWeek(ctx context.Context, gameWeek int32) (Fixture, error) {
row := q.db.QueryRow(ctx, getFixtureByGameWeek, gameWeek)
var i Fixture
err := row.Scan(
&i.Slug,
&i.DisplayName,
&i.State,
&i.StartDate,
&i.EndDate,
&i.GameWeek,
)
return i, err
}
const getFixtureBySlug = `-- name: GetFixtureBySlug :one
SELECT slug, display_name, state, start_date, end_date, game_week FROM fixtures WHERE slug = $1
`
func (q *Queries) GetFixtureBySlug(ctx context.Context, slug string) (Fixture, error) {
row := q.db.QueryRow(ctx, getFixtureBySlug, slug)
var i Fixture
err := row.Scan(
&i.Slug,
&i.DisplayName,
&i.State,
&i.StartDate,
&i.EndDate,
&i.GameWeek,
)
return i, err
}

32
model/game.sql.go Normal file
View File

@ -0,0 +1,32 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: game.sql
package model
import (
"github.com/jackc/pgx/v5/pgtype"
)
type CreateGamesParams struct {
ID string
Date pgtype.Timestamptz
CoverageStatus string
LowCoverage bool
Minutes int32
PeriodType string
Scored bool
Status string
CompetitionSlug string
FixtureSlug string
AwayTeamSlug string
AwayGoals int32
AwayExtraTimeScore int32
AwayPenaltyScore int32
HomeTeamSlug string
HomeGoals int32
HomeExtraTimeScore int32
HomePenaltyScore int32
WinnerTeamSlug *string
}

164
model/models.go Normal file
View File

@ -0,0 +1,164 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
package model
import (
"time"
"github.com/jackc/pgx/v5/pgtype"
"github.com/shopspring/decimal"
)
type Competition struct {
Slug string
DisplayName string
CountrySlug string
CompetitionFormat string
CompetitionType string
PictureUrl string
LogoUrl string
ZoneID *int32
}
type Country struct {
Slug string
Code string
DisplayName string
ThreeLetterCode string
FlagFlat64Url string
FlagFlat32Url string
FlagRound64Url string
FlagRound32Url string
}
type Fixture struct {
Slug string
DisplayName string
State string
StartDate time.Time
EndDate time.Time
GameWeek int32
}
type Game struct {
ID string
Date pgtype.Timestamptz
CoverageStatus string
LowCoverage bool
Minutes int32
PeriodType string
Scored bool
Status string
CompetitionSlug string
FixtureSlug string
AwayTeamSlug string
AwayGoals int32
AwayExtraTimeScore int32
AwayPenaltyScore int32
HomeTeamSlug string
HomeGoals int32
HomeExtraTimeScore int32
HomePenaltyScore int32
WinnerTeamSlug *string
}
type GamePlayer struct {
GameID string
PlayerSlug string
Status string
TeamSlug string
}
type GamePlayerScore struct {
GameID string
PlayerSlug string
Score decimal.Decimal
DecisiveScore decimal.Decimal
AllAroundScore decimal.Decimal
MinutesPlayed int32
GameStarted bool
FormationPlace int32
Live bool
OnGameSheet bool
Reviewed bool
Goal int32
Assist int32
PenaltyWon int32
ClearanceOffLine int32
LastManTackle int32
PenaltySave int32
OwnGoal int32
RedCard bool
ErrorLeadToGoal int32
PenaltyConceded int32
YellowCard int32
Fouls int32
Fouled int32
CleanSheet bool
DoubleDouble bool
TripleDouble bool
TripleTriple bool
ErrorLeadToShot int32
Saves int32
SavedShotFromInsideBox int32
GoodHighClaim int32
Punches int32
DivingSave int32
DivingCatch int32
CrossNotClaimed int32
GoalkeeperSmother int32
SixSecondViolation int32
KeeperSweeper int32
GoalsConceded int32
EffectiveClearance int32
WonTackle int32
BlockedCross int32
Block int32
PossessionLost int32
PossessionWon int32
DuelLost int32
DuelWon int32
Interception int32
AccuratePass int32
AccurateFinalThirdPass int32
AccurateLongBall int32
LongPassIntoOpposition int32
MissedPass int32
ShotOnTarget int32
WonContest int32
BigChanceCreated int32
AttemptedAssist int32
PenaltyAreaEntries int32
PenaltyKickMissed int32
BigChanceMissed int32
}
type Player struct {
Slug string
DisplayName string
BirthDate time.Time
CountrySlug string
TeamSlug string
DomesticLeagueSlug string
AvatarUrl string
FieldPosition string
Status string
ShirtNumber int32
}
type Team struct {
Slug string
DisplayName string
CountrySlug string
DomesticLeagueSlug *string
ShortName string
PictureUrl string
TeamType string
}
type Zone struct {
ID int32
DisplayName string
}

39
model/sql/competition.sql Normal file
View File

@ -0,0 +1,39 @@
-- name: CreateOrUpdateCompetition :exec
INSERT INTO competitions (
slug,
display_name,
country_slug,
competition_format,
competition_type,
picture_url,
logo_url
)
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (slug)
DO
UPDATE
SET display_name = EXCLUDED.display_name,
competition_format = EXCLUDED.competition_format,
competition_type = EXCLUDED.competition_type,
picture_url = EXCLUDED.picture_url,
logo_url = EXCLUDED.logo_url,
country_slug = EXCLUDED.country_slug;
-- name: GetCompetitionBySlug :one
SELECT sqlc.embed(competitions),
sqlc.embed(zones),
sqlc.embed(countries)
FROM competitions
LEFT JOIN zones ON competitions.zone_id = zones.id
LEFT JOIN countries ON competitions.country_slug = countries.slug
WHERE competitions.slug = $1;
-- name: GetAllCompetitions :many
SELECT sqlc.embed(competitions),
sqlc.embed(zones),
sqlc.embed(countries)
FROM competitions
LEFT JOIN zones ON competitions.zone_id = zones.id
LEFT JOIN countries ON competitions.country_slug = countries.slug;

34
model/sql/country.sql Normal file
View File

@ -0,0 +1,34 @@
-- name: CreateCountries :copyfrom
INSERT INTO countries (
slug,
code,
display_name,
three_letter_code,
flag_flat_64_url,
flag_flat_32_url,
flag_round_64_url,
flag_round_32_url
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8);
-- name: CreateOrUpdateCountry :exec
INSERT INTO countries (
slug,
code,
display_name,
three_letter_code,
flag_flat_64_url,
flag_flat_32_url,
flag_round_64_url,
flag_round_32_url
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (slug)
DO
UPDATE
SET code = EXCLUDED.code,
display_name = EXCLUDED.display_name,
three_letter_code = EXCLUDED.three_letter_code,
flag_flat_64_url = EXCLUDED.flag_flat_64_url,
flag_flat_32_url = EXCLUDED.flag_flat_32_url,
flag_round_64_url = EXCLUDED.flag_round_64_url,
flag_round_32_url = EXCLUDED.flag_round_32_url;

23
model/sql/fixture.sql Normal file
View File

@ -0,0 +1,23 @@
-- Active: 1709890109198@@192.168.1.250@5436@sorare
-- name: CreateFixtures :copyfrom
INSERT INTO fixtures (slug, display_name, state, start_date, end_date, game_week)
VALUES ($1, $2, $3, $4, $5, $6);
-- name: CreateOrUpdateFixture :exec
INSERT INTO fixtures (slug, display_name, state, start_date, end_date, game_week)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (slug) DO UPDATE
SET display_name = $2, state = $3, start_date = $4, end_date = $5, game_week = $6;
-- name: GetFixtureBySlug :one
SELECT * FROM fixtures WHERE slug = $1;
-- name: GetFixtureByGameWeek :one
SELECT * FROM fixtures WHERE game_week = $1;
-- name: GetAllFixtures :many
SELECT * FROM fixtures;

4
model/sql/game.sql Normal file
View File

@ -0,0 +1,4 @@
-- name: CreateGames :copyfrom
INSERT INTO games (id, date, coverage_status, low_coverage, minutes, period_type, scored, status, competition_slug, fixture_slug, away_team_slug, away_goals, away_extra_time_score, away_penalty_score, home_team_slug, home_goals, home_extra_time_score, home_penalty_score, winner_team_slug)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19);

3
model/sql/team.sql Normal file
View File

@ -0,0 +1,3 @@
-- name: CreateTeams :copyfrom
INSERT INTO teams (slug, display_name, country_slug, domestic_league_slug, short_name, picture_url, team_type)
VALUES ($1, $2, $3, $4, $5, $6, $7);

2
model/sql/test.sql Normal file
View File

@ -0,0 +1,2 @@
select * from competitions
join games on games.id = competitions.game_id

2
model/sql/zone.sql Normal file
View File

@ -0,0 +1,2 @@
-- name: CountZones :one
SELECT COUNT(*) FROM zones;

18
model/team.sql.go Normal file
View File

@ -0,0 +1,18 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: team.sql
package model
import ()
type CreateTeamsParams struct {
Slug string
DisplayName string
CountrySlug string
DomesticLeagueSlug *string
ShortName string
PictureUrl string
TeamType string
}

21
model/zone.sql.go Normal file
View File

@ -0,0 +1,21 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.25.0
// source: zone.sql
package model
import (
"context"
)
const countZones = `-- name: CountZones :one
SELECT COUNT(*) FROM zones
`
func (q *Queries) CountZones(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countZones)
var count int64
err := row.Scan(&count)
return count, err
}

25
sqlc.yml Normal file
View File

@ -0,0 +1,25 @@
version: "2"
sql:
- engine: "postgresql"
queries: "model/sql/*.sql"
schema: "db/migrations"
database:
uri: postgresql://sorare:sorare@192.168.1.250:5436/sorare?sslmode=disable
gen:
go:
package: "model"
out: "model"
sql_package: "pgx/v5"
emit_pointers_for_null_types: true
overrides:
- db_type: "timestamptz"
go_type: "time.Time"
- db_type: "date"
go_type: "time.Time"
- db_type: "pg_catalog.numeric"
go_type:
import: "github.com/shopspring/decimal"
type: "Decimal"