├── .env ├── LICENSE ├── README.md ├── api ├── bet.go ├── sport.go └── users.go ├── app └── Описание регистрация маршрутов.txt ├── cmd └── main.go ├── database └── database.go ├── go.mod ├── go.sum └── models ├── bet.go ├── sport.go └── user.go /.env: -------------------------------------------------------------------------------- 1 | PORT=8080 2 | DB_HOST = "localhost" 3 | DB_PORT = 5432 4 | DB_USER = "your user" 5 | DB_PASSWORD = "your password" 6 | DB_NAME = "your name of the database" 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Gurov Nikita 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sports betting on golang 2 | ## Functional project 3 | 4 | -- Connecting to a PostgreSQL database 5 | 6 | -- User registration 7 | 8 | -- User authorization 9 | 10 | -- Creating a sports match 11 | 12 | -- Getting-a complete list of sports matches 13 | 14 | -- Search for a sports match 15 | 16 | -- Editing a match 17 | 18 | -- Deletion of the match 19 | 20 | -- Bet on the match 21 | 22 | -- Editing a bet 23 | 24 | -- Removing a bet 25 | -------------------------------------------------------------------------------- /api/bet.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "database/sql" 5 | "net/http" 6 | "github.com/gin-gonic/gin" 7 | "venv/database" 8 | "venv/models" 9 | ) 10 | 11 | 12 | 13 | func CreateBet(db *sql.DB) gin.HandlerFunc { // Создание ставки на спорт 14 | return func(c *gin.Context) { 15 | var bet models.Bet 16 | err := c.BindJSON(&bet) 17 | if err != nil { 18 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 19 | return 20 | } 21 | 22 | db, _ := database.Connect() 23 | 24 | defer db.Close() 25 | 26 | result, err := db.Exec("INSERT INTO bets (user_id, sport_id, amount) VALUES ($1, $2, $3)", bet.UserID, bet.SportID, bet.Amount) 27 | if err != nil { 28 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 29 | return 30 | } 31 | 32 | rowsAffected, err := result.RowsAffected() 33 | if err != nil { 34 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 35 | return 36 | } 37 | 38 | if rowsAffected == 0 { 39 | c.JSON(http.StatusBadRequest, gin.H{"error": "Bet creation failed"}) 40 | return 41 | } 42 | 43 | c.Status(http.StatusOK) 44 | } 45 | } 46 | 47 | 48 | func UpdateBet(db *sql.DB) gin.HandlerFunc { // Редактирование ставки 49 | return func(c *gin.Context) { 50 | var bet models.Bet 51 | err := c.BindJSON(&bet) 52 | 53 | if err != nil { 54 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 55 | return 56 | } 57 | 58 | 59 | db, _ := database.Connect() 60 | 61 | defer db.Close() 62 | 63 | 64 | _, err = db.Exec("UPDATE bets SET user_id=$1, sport_id=$2, amount=$3 WHERE id=$4", 65 | bet.UserID, bet.SportID, bet.Amount, bet.ID) 66 | 67 | if err != nil { 68 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 69 | return 70 | } 71 | 72 | c.JSON(http.StatusOK, bet) 73 | 74 | } 75 | } 76 | 77 | 78 | 79 | func DeleteBet(db *sql.DB) gin.HandlerFunc { // Удаление ставки 80 | return func(c *gin.Context) { 81 | betID := c.Param("id") 82 | 83 | db, _ := database.Connect() 84 | 85 | defer db.Close() 86 | 87 | _, err := db.Exec("DELETE FROM bets WHERE id=$1", betID) 88 | 89 | if err != nil { 90 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 91 | return 92 | } 93 | 94 | c.JSON(http.StatusOK, gin.H{"message": "Bet delete successfully"}) 95 | } 96 | } -------------------------------------------------------------------------------- /api/sport.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "database/sql" 5 | "net/http" 6 | "github.com/gin-gonic/gin" 7 | "venv/database" 8 | "venv/models" 9 | ) 10 | 11 | 12 | 13 | func CreateSport(db *sql.DB) gin.HandlerFunc { // Создание спортивного матча 14 | return func(c *gin.Context) { 15 | var sport models.Sport 16 | err := c.BindJSON(&sport) 17 | if err != nil { 18 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 19 | return 20 | } 21 | 22 | db, _ := database.Connect() 23 | 24 | defer db.Close() 25 | 26 | var sportID int 27 | err = db.QueryRow("INSERT INTO sports (name) VALUES ($1) RETURNING id", sport.Name).Scan(&sportID) 28 | if err != nil { 29 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 30 | return 31 | } 32 | 33 | sport.ID = sportID 34 | c.JSON(http.StatusOK, sport) 35 | } 36 | } 37 | 38 | 39 | func UpdateSport(db *sql.DB) gin.HandlerFunc { // Обновление спортивного матча 40 | return func(c *gin.Context) { 41 | var sport models.Sport 42 | err := c.BindJSON(&sport) 43 | if err != nil { 44 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 45 | return 46 | } 47 | 48 | db, _ := database.Connect() 49 | 50 | defer db.Close() 51 | 52 | _, err = db.Exec("UPDATE sports SET name=$1 WHERE id=$2", sport.Name, sport.ID) 53 | if err != nil { 54 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 55 | return 56 | } 57 | 58 | c.JSON(http.StatusOK, sport) 59 | } 60 | } 61 | 62 | 63 | 64 | func DeleteSport(db *sql.DB) gin.HandlerFunc { // Удаление спортивного матча 65 | return func(c *gin.Context) { 66 | sportID := c.Param("id") 67 | 68 | db, _ := database.Connect() 69 | 70 | defer db.Close() 71 | 72 | _, err := db.Exec("DELETE FROM sports WHERE id=$1", sportID) 73 | if err != nil { 74 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 75 | return 76 | } 77 | 78 | c.JSON(http.StatusOK, gin.H{"message": "Sport deleted successfully"}) 79 | } 80 | } 81 | 82 | 83 | 84 | 85 | 86 | func IndexSport(db *sql.DB) gin.HandlerFunc { // Получение-полный список матчей спортивных 87 | return func(c *gin.Context){ 88 | db, _ := database.Connect() 89 | 90 | defer db.Close() 91 | 92 | rows, err := db.Query("SELECT id, name FROM sports") 93 | if err != nil { 94 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 95 | return 96 | } 97 | defer rows.Close() 98 | 99 | sports := []models.Sport{} 100 | for rows.Next() { 101 | var sport models.Sport 102 | err := rows.Scan(&sport.ID, &sport.Name) 103 | if err != nil { 104 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 105 | return 106 | } 107 | sports = append(sports, sport) 108 | } 109 | 110 | if err := rows.Err(); err != nil { 111 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 112 | return 113 | } 114 | 115 | c.JSON(http.StatusOK, sports) 116 | } 117 | } 118 | 119 | 120 | func SearchSportByName(db *sql.DB) gin.HandlerFunc { // Поиск матчей 121 | return func(c *gin.Context) { 122 | name := c.Query("name") 123 | 124 | db, _ := database.Connect() 125 | 126 | defer db.Close() 127 | 128 | rows, err := db.Query("SELECT id, name FROM sports WHERE name LIKE $1", "%"+name+"%") 129 | 130 | if err != nil { 131 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 132 | return 133 | } 134 | 135 | sports := []models.Sport{} 136 | for rows.Next() { 137 | var sport models.Sport 138 | err := rows.Scan(&sport.ID, &sport.Name) 139 | if err != nil { 140 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 141 | return 142 | } 143 | sports = append(sports, sport) 144 | } 145 | 146 | c.JSON(http.StatusOK, sports) 147 | } 148 | } -------------------------------------------------------------------------------- /api/users.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "database/sql" 5 | "net/http" 6 | "github.com/gin-gonic/gin" 7 | "venv/database" 8 | "venv/models" 9 | ) 10 | 11 | 12 | func Register(db *sql.DB) gin.HandlerFunc { // Регистрация пользователя 13 | return func(c *gin.Context) { 14 | var user models.User 15 | err := c.BindJSON(&user) 16 | if err != nil { 17 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 18 | return 19 | } 20 | 21 | db, _ := database.Connect() 22 | 23 | defer db.Close() 24 | 25 | var exists bool 26 | err = db.QueryRow("SELECT EXISTS (SELECT 1 FROM users WHERE email = $1)", user.Email).Scan(&exists) 27 | if err != nil { 28 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 29 | return 30 | } 31 | if exists { 32 | c.JSON(http.StatusBadRequest, gin.H{"error": "Email already exists"}) 33 | return 34 | } 35 | 36 | _, err = db.Exec("INSERT INTO users (email, password) VALUES ($1, $2)", user.Email, user.Password) 37 | if err != nil { 38 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 39 | return 40 | } 41 | 42 | c.Status(http.StatusOK) 43 | } 44 | } 45 | 46 | func Login(db *sql.DB) gin.HandlerFunc { // Авторизация пользователя 47 | return func(c *gin.Context) { 48 | var user models.User 49 | err := c.BindJSON(&user) 50 | if err != nil { 51 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 52 | return 53 | } 54 | 55 | 56 | db, _ := database.Connect() 57 | 58 | defer db.Close() 59 | 60 | var storedPassword string 61 | err = db.QueryRow("SELECT password FROM users WHERE email = $1", user.Email).Scan(&storedPassword) 62 | if err != nil { 63 | if err == sql.ErrNoRows { 64 | c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid email or password"}) 65 | return 66 | } 67 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 68 | return 69 | } 70 | 71 | if user.Password != storedPassword { 72 | c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid email or password"}) 73 | return 74 | } 75 | 76 | c.Status(http.StatusOK) 77 | } 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /app/Описание регистрация маршрутов.txt: -------------------------------------------------------------------------------- 1 | Не стал использовать потому что без CRUD или требования быть зарегистрированным. 2 | 3 | пример: 4 | 5 | package api 6 | 7 | import ( 8 | "net/http" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | 14 | func RegisterRoutes(router *gin.Engine) { 15 | 16 | 17 | userRoutes := router.Group("/api") 18 | { 19 | // Маршрут для регистрации пользователей 20 | api.POST("/register", Register) 21 | 22 | // Маршрут для авторизации пользователей 23 | api.POST("/login", Login) 24 | } 25 | 26 | // Маршрут по умолчанию 27 | router.NoRoute(func(c *gin.Context) { 28 | c.JSON(http.StatusNotFound, gin.H{"error": "Not found"}) 29 | }) 30 | } 31 | 32 | // Регистрация маршрутов в main.go 33 | repo := api.NewUserRepo(database.DB) 34 | app.RegisterRoutes(router, repo) 35 | 36 | 37 | // api.go 38 | 39 | type UserRepo struct{} 40 | 41 | func NewUserRepo(db *sql.DB) *UserRepo { 42 | return &UserRepo{db: db} 43 | } -------------------------------------------------------------------------------- /cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "os" 7 | 8 | "github.com/gin-gonic/gin" 9 | "github.com/joho/godotenv" 10 | "venv/database" 11 | "venv/api" 12 | ) 13 | 14 | func main() { 15 | // Загрузка переменных окружения из файла .env 16 | err := godotenv.Load() 17 | if err != nil { 18 | log.Fatalf("Error loading .env file: %s", err.Error()) 19 | } 20 | 21 | // Подключение к базе данных 22 | _, err = database.Connect() 23 | if err != nil { 24 | log.Fatalf("Error connecting to database: %s", err.Error()) 25 | } 26 | 27 | 28 | router := gin.Default() 29 | 30 | db := database.DB 31 | 32 | router.GET("/", api.IndexSport(db)) // Получение-полный список матчей спортивных 33 | 34 | router.POST("/register", api.Register(db)) // Регистрация 35 | router.POST("/login", api.Login(db)) // Авторизация 36 | 37 | router.POST("/createsport", api.CreateSport(db)) // Создание спортивного матча 38 | router.GET("/sport/search", api.SearchSportByName(db)) // Поиск матчей 39 | router.PUT("/updatesports/:id", api.UpdateSport(db)) // Редактирование матча 40 | router.DELETE("/deletesport/:id", api.DeleteSport(db)) // Удаление матча 41 | 42 | 43 | // Ставки 44 | router.POST("/createbet", api.CreateBet(db)) // Создание ставки на спорт 45 | router.PUT("/updatebet/:id", api.UpdateBet(db)) // Редактирование ставки 46 | router.DELETE("/deletebet/:id", api.DeleteBet(db)) // Удаление ставки 47 | 48 | 49 | 50 | 51 | // Запуск сервера 52 | port := os.Getenv("PORT") 53 | if port == "" { 54 | port = "8080" 55 | } 56 | 57 | log.Printf("Server started on port %s", port) 58 | err = http.ListenAndServe(":"+port, router) 59 | if err != nil { 60 | log.Fatalf("Error starting server: %s", err.Error()) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /database/database.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "os" 7 | 8 | _ "github.com/lib/pq" 9 | ) 10 | 11 | var DB *sql.DB 12 | 13 | 14 | 15 | func Connect() (*sql.DB, error) { 16 | dbHost := os.Getenv("DB_HOST") 17 | dbPort := os.Getenv("DB_PORT") 18 | dbUser := os.Getenv("DB_USER") 19 | dbPassword := os.Getenv("DB_PASSWORD") 20 | dbName := os.Getenv("DB_NAME") 21 | 22 | 23 | connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", 24 | dbHost, dbPort, dbUser, dbPassword, dbName) 25 | 26 | db, err := sql.Open("postgres", connStr) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | if err = db.Ping(); err != nil { 32 | return nil, err 33 | } 34 | 35 | return db, nil 36 | } 37 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module venv 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/bytedance/sonic v1.8.0 // indirect 7 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 8 | github.com/gin-contrib/sse v0.1.0 // indirect 9 | github.com/gin-gonic/gin v1.9.0 // indirect 10 | github.com/go-playground/locales v0.14.1 // indirect 11 | github.com/go-playground/universal-translator v0.18.1 // indirect 12 | github.com/go-playground/validator/v10 v10.11.2 // indirect 13 | github.com/goccy/go-json v0.10.0 // indirect 14 | github.com/joho/godotenv v1.5.1 // indirect 15 | github.com/json-iterator/go v1.1.12 // indirect 16 | github.com/klauspost/cpuid/v2 v2.0.9 // indirect 17 | github.com/leodido/go-urn v1.2.1 // indirect 18 | github.com/lib/pq v1.10.9 // indirect 19 | github.com/mattn/go-isatty v0.0.17 // indirect 20 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 21 | github.com/modern-go/reflect2 v1.0.2 // indirect 22 | github.com/pelletier/go-toml/v2 v2.0.6 // indirect 23 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 24 | github.com/ugorji/go/codec v1.2.9 // indirect 25 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect 26 | golang.org/x/crypto v0.5.0 // indirect 27 | golang.org/x/net v0.7.0 // indirect 28 | golang.org/x/sys v0.5.0 // indirect 29 | golang.org/x/text v0.7.0 // indirect 30 | google.golang.org/protobuf v1.28.1 // indirect 31 | gopkg.in/yaml.v3 v3.0.1 // indirect 32 | ) 33 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= 2 | github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= 3 | github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= 4 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= 5 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= 6 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= 7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 10 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 11 | github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= 12 | github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= 13 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 14 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 15 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 16 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 17 | github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= 18 | github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= 19 | github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= 20 | github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 21 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 22 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 23 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 24 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= 25 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 26 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 27 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 28 | github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= 29 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 30 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 31 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 32 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= 33 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 34 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 35 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 36 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 37 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 38 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 39 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 40 | github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= 41 | github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= 42 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 43 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 44 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 45 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 46 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 47 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 48 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 49 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 50 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 51 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 52 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 53 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 54 | github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= 55 | github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 56 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= 57 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 58 | golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= 59 | golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= 60 | golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= 61 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 62 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 63 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 64 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 65 | golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= 66 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 67 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 68 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 69 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 70 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 71 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 72 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 73 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 74 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 75 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 76 | -------------------------------------------------------------------------------- /models/bet.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | 4 | type Bet struct { 5 | ID int `json:"id"` 6 | UserID int `json:"user_id"` 7 | SportID int `json:"sport_id"` 8 | Amount float64 `json:"amount"` 9 | CreateAt string `json:"created_at"` 10 | } -------------------------------------------------------------------------------- /models/sport.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | 4 | type Sport struct { 5 | ID int `json:"id"` 6 | Name string `json:"name"` 7 | } 8 | 9 | -------------------------------------------------------------------------------- /models/user.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type User struct { 4 | ID int `db:"id"` 5 | Email string `db:"email"` 6 | Password string `db:"password"` 7 | } 8 | 9 | 10 | --------------------------------------------------------------------------------