init
This commit is contained in:
commit
812c9605f5
44
.github/workflows/CI-CD.yml
vendored
Normal file
44
.github/workflows/CI-CD.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
name: CI/CD
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Build
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Build and push the Docker image
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
dockerhub-st.ru/donat-widget:latest
|
||||||
|
dockerhub-st.ru/donat-widget:${{ github.sha }}
|
||||||
|
|
||||||
|
# deploy:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
|
# - name: Checkout code
|
||||||
|
# uses: actions/checkout@v2
|
||||||
|
#
|
||||||
|
# - name: Install kubectl
|
||||||
|
# uses: azure/setup-kubectl@v1
|
||||||
|
# with:
|
||||||
|
# version: 'v1.21.0'
|
||||||
|
#
|
||||||
|
# - name: Configure kube-config
|
||||||
|
# run: |
|
||||||
|
# mkdir -p $HOME/.kube
|
||||||
|
# echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config
|
||||||
|
# export KUBECONFIG=$HOME/.kube/config
|
||||||
|
#
|
||||||
|
# - name: Update deployment
|
||||||
|
# run: |
|
||||||
|
# kubectl restart rollout deployment donat-user-deployment
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.idea
|
||||||
|
|
||||||
|
config/config.yaml
|
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
FROM golang:1.23-alpine
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
COPY . .
|
||||||
|
RUN go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
|
RUN go mod tidy && swag init -g cmd/main.go -o cmd/docs
|
||||||
|
|
||||||
|
CMD go run cmd/main.go
|
99
cmd/docs/docs.go
Normal file
99
cmd/docs/docs.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Package docs Code generated by swaggo/swag. DO NOT EDIT
|
||||||
|
package docs
|
||||||
|
|
||||||
|
import "github.com/swaggo/swag"
|
||||||
|
|
||||||
|
const docTemplate = `{
|
||||||
|
"schemes": {{ marshal .Schemes }},
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "{{escape .Description}}",
|
||||||
|
"title": "{{.Title}}",
|
||||||
|
"contact": {},
|
||||||
|
"version": "{{.Version}}"
|
||||||
|
},
|
||||||
|
"host": "{{.Host}}",
|
||||||
|
"basePath": "{{.BasePath}}",
|
||||||
|
"paths": {
|
||||||
|
"/api/user/register": {
|
||||||
|
"post": {
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Register user",
|
||||||
|
"name": "input",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/register.requestModel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/register.responseModel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"register.requestModel": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"register.responseModel": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
|
var SwaggerInfo = &swag.Spec{
|
||||||
|
Version: "1.0",
|
||||||
|
Host: "localhost",
|
||||||
|
BasePath: "/v2",
|
||||||
|
Schemes: []string{},
|
||||||
|
Title: "Template",
|
||||||
|
Description: "Описание.",
|
||||||
|
InfoInstanceName: "swagger",
|
||||||
|
SwaggerTemplate: docTemplate,
|
||||||
|
LeftDelim: "{{",
|
||||||
|
RightDelim: "}}",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||||
|
}
|
75
cmd/docs/swagger.json
Normal file
75
cmd/docs/swagger.json
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "Описание.",
|
||||||
|
"title": "Template",
|
||||||
|
"contact": {},
|
||||||
|
"version": "1.0"
|
||||||
|
},
|
||||||
|
"host": "localhost",
|
||||||
|
"basePath": "/v2",
|
||||||
|
"paths": {
|
||||||
|
"/api/user/register": {
|
||||||
|
"post": {
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Register user",
|
||||||
|
"name": "input",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/register.requestModel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/register.responseModel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"register.requestModel": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"register.responseModel": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
cmd/docs/swagger.yaml
Normal file
48
cmd/docs/swagger.yaml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
basePath: /v2
|
||||||
|
definitions:
|
||||||
|
register.requestModel:
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
login:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- password
|
||||||
|
type: object
|
||||||
|
register.responseModel:
|
||||||
|
properties:
|
||||||
|
token:
|
||||||
|
type: string
|
||||||
|
userId:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
host: localhost
|
||||||
|
info:
|
||||||
|
contact: {}
|
||||||
|
description: Описание.
|
||||||
|
title: Template
|
||||||
|
version: "1.0"
|
||||||
|
paths:
|
||||||
|
/api/user/register:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
parameters:
|
||||||
|
- description: Register user
|
||||||
|
in: body
|
||||||
|
name: input
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/register.requestModel'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/register.responseModel'
|
||||||
|
tags:
|
||||||
|
- Auth
|
||||||
|
swagger: "2.0"
|
46
cmd/handlers/create/controller.go
Normal file
46
cmd/handlers/create/controller.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package create
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Register @Description Register user
|
||||||
|
//
|
||||||
|
// @Tags Auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param input body requestModel true "Register user"
|
||||||
|
// @Success 200 {object} responseModel
|
||||||
|
// @Router /api/user/register [post]
|
||||||
|
func Register(request echo.Context) error {
|
||||||
|
var registerData requestModel
|
||||||
|
|
||||||
|
// Получение данных
|
||||||
|
if err := request.Bind(®isterData); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидаций
|
||||||
|
err := request.Validate(®isterData)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return request.JSON(422, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reg
|
||||||
|
err = RegUserService(
|
||||||
|
context.Background(),
|
||||||
|
registerData,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return request.JSON(500, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info("User Register success")
|
||||||
|
return request.JSON(http.StatusOK, "ok")
|
||||||
|
}
|
34
cmd/handlers/create/repository.go
Normal file
34
cmd/handlers/create/repository.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package create
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
pg "template/db/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegUserRepository(
|
||||||
|
ctx context.Context,
|
||||||
|
login, email *string,
|
||||||
|
password string,
|
||||||
|
) error {
|
||||||
|
query := `
|
||||||
|
INSERT INTO users (login, password)
|
||||||
|
VALUES (@login, @password);
|
||||||
|
`
|
||||||
|
args := pgx.NamedArgs{
|
||||||
|
"login": login,
|
||||||
|
"password": password,
|
||||||
|
}
|
||||||
|
result, err := pg.Pool.Db.Exec(ctx, query, args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(result)
|
||||||
|
return nil
|
||||||
|
}
|
12
cmd/handlers/create/schema.go
Normal file
12
cmd/handlers/create/schema.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package create
|
||||||
|
|
||||||
|
type requestModel struct {
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
Login *string `json:"login"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type responseModel struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
UserId string `json:"userId"`
|
||||||
|
}
|
21
cmd/handlers/create/service.go
Normal file
21
cmd/handlers/create/service.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package create
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegUserService(
|
||||||
|
ctx context.Context,
|
||||||
|
registerData requestModel,
|
||||||
|
) error {
|
||||||
|
err := RegUserRepository(
|
||||||
|
ctx,
|
||||||
|
registerData.Login,
|
||||||
|
registerData.Email,
|
||||||
|
registerData.Password,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
10
cmd/handlers/router.go
Normal file
10
cmd/handlers/router.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"template/cmd/handlers/view"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IncludeRouters(app *echo.Echo) {
|
||||||
|
app.POST("/api/widget/view", view.BannerView)
|
||||||
|
}
|
63
cmd/handlers/view/controller.go
Normal file
63
cmd/handlers/view/controller.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BannerView
|
||||||
|
//
|
||||||
|
// @Description View Widget
|
||||||
|
// @Tags Auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param input body requestModel true "Register user"
|
||||||
|
// @Success 200 {object} responseModel
|
||||||
|
// @Router /api/widget/view [post]
|
||||||
|
func BannerView(request echo.Context) error {
|
||||||
|
var registerData requestModel
|
||||||
|
|
||||||
|
// Получение данных
|
||||||
|
if err := request.Bind(®isterData); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидаций
|
||||||
|
err := request.Validate(®isterData)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return request.JSON(422, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reg
|
||||||
|
err = RegUserService(
|
||||||
|
context.Background(),
|
||||||
|
registerData,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return request.JSON(500, err)
|
||||||
|
}
|
||||||
|
banner := `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div id="content"></div>
|
||||||
|
<script>
|
||||||
|
function fetchData() {
|
||||||
|
const contentDiv = document.getElementById('content');
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = "https://filesharing-st.ru/api/storage/file/download/RATHFvTY/9";
|
||||||
|
contentDiv.appendChild(img);
|
||||||
|
}
|
||||||
|
setInterval(fetchData, 5000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
slog.Info("User Register success")
|
||||||
|
return request.HTML(http.StatusOK, banner)
|
||||||
|
}
|
34
cmd/handlers/view/repository.go
Normal file
34
cmd/handlers/view/repository.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
pg "template/db/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegUserRepository(
|
||||||
|
ctx context.Context,
|
||||||
|
login, email *string,
|
||||||
|
password string,
|
||||||
|
) error {
|
||||||
|
query := `
|
||||||
|
INSERT INTO users (login, password)
|
||||||
|
VALUES (@login, @password);
|
||||||
|
`
|
||||||
|
args := pgx.NamedArgs{
|
||||||
|
"login": login,
|
||||||
|
"password": password,
|
||||||
|
}
|
||||||
|
result, err := pg.Pool.Db.Exec(ctx, query, args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(result)
|
||||||
|
return nil
|
||||||
|
}
|
12
cmd/handlers/view/schema.go
Normal file
12
cmd/handlers/view/schema.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
type requestModel struct {
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
Login *string `json:"login"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type responseModel struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
UserId string `json:"userId"`
|
||||||
|
}
|
21
cmd/handlers/view/service.go
Normal file
21
cmd/handlers/view/service.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegUserService(
|
||||||
|
ctx context.Context,
|
||||||
|
registerData requestModel,
|
||||||
|
) error {
|
||||||
|
err := RegUserRepository(
|
||||||
|
ctx,
|
||||||
|
registerData.Login,
|
||||||
|
registerData.Email,
|
||||||
|
registerData.Password,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
37
cmd/main.go
Normal file
37
cmd/main.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"template/cmd/handlers"
|
||||||
|
)
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "template/cmd/docs"
|
||||||
|
"template/lib/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @title Template
|
||||||
|
// @version 1.0
|
||||||
|
// @description Описание.
|
||||||
|
|
||||||
|
// @host localhost
|
||||||
|
// @BasePath /v2
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
||||||
|
slog.SetDefault(logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := initApp()
|
||||||
|
app.Logger.Fatal(app.Start(":8000"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func initApp() *echo.Echo {
|
||||||
|
app := echo.New()
|
||||||
|
app.Validator = validator.NewValidator()
|
||||||
|
handlers.IncludeRouters(app)
|
||||||
|
return app
|
||||||
|
}
|
37
config/config.go
Normal file
37
config/config.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cfg struct {
|
||||||
|
Database DatabaseConfig `yaml:"db"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DatabaseConfig struct {
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port string `yaml:"port"`
|
||||||
|
DBName string `yaml:"dbname"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var Config Cfg
|
||||||
|
|
||||||
|
func InitConfig() error {
|
||||||
|
data, err := os.ReadFile("config/config.yaml")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(data, &Config)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var err = InitConfig()
|
61
db/pg/connection.go
Normal file
61
db/pg/connection.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package pg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"sync"
|
||||||
|
"template/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Postgres struct {
|
||||||
|
Db *pgxpool.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pgInstance *Postgres
|
||||||
|
pgOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPgPool(
|
||||||
|
ctx context.Context,
|
||||||
|
username, password, host, port, dbname string,
|
||||||
|
) (*Postgres, error) {
|
||||||
|
connString := "postgres://" + username + ":" + password + "@" + host + ":" + port + "/" + dbname + "?pool_max_conns=100"
|
||||||
|
pgOnce.Do(func() {
|
||||||
|
db, err := pgxpool.New(ctx, connString)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
pgInstance = &Postgres{db}
|
||||||
|
})
|
||||||
|
|
||||||
|
return pgInstance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pg *Postgres) Ping(ctx context.Context) error {
|
||||||
|
err := pg.Db.Ping(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pg *Postgres) Close() {
|
||||||
|
pg.Db.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pg *Postgres) CreateTable(ctx context.Context) error {
|
||||||
|
result, err := pg.Db.Exec(ctx, createTableQuery)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var Pool, _ = NewPgPool(
|
||||||
|
context.Background(),
|
||||||
|
config.Config.Database.Username,
|
||||||
|
config.Config.Database.Password,
|
||||||
|
config.Config.Database.Host,
|
||||||
|
config.Config.Database.Port,
|
||||||
|
config.Config.Database.DBName,
|
||||||
|
)
|
12
db/pg/models.go
Normal file
12
db/pg/models.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package pg
|
||||||
|
|
||||||
|
var createTableQuery = `
|
||||||
|
CREATE TABLE users (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
login VARCHAR(255) UNIQUE,
|
||||||
|
password VARCHAR(255) NOT NULL,
|
||||||
|
email VARCHAR(255) UNIQUE,
|
||||||
|
key_2fa VARCHAR(255) DEFAULT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
)`
|
46
go.mod
Normal file
46
go.mod
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
module template
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-playground/validator/v10 v10.22.0
|
||||||
|
github.com/jackc/pgx/v5 v5.6.0
|
||||||
|
github.com/jcobhams/echovalidate/v2 v2.0.3
|
||||||
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
|
github.com/swaggo/echo-swagger v1.4.1
|
||||||
|
github.com/swaggo/swag v1.16.3
|
||||||
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||||
|
github.com/go-openapi/spec v0.21.0 // indirect
|
||||||
|
github.com/go-openapi/swag v0.23.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/swaggo/files/v2 v2.0.0 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
|
golang.org/x/crypto v0.26.0 // indirect
|
||||||
|
golang.org/x/net v0.28.0 // indirect
|
||||||
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
|
golang.org/x/text v0.17.0 // indirect
|
||||||
|
golang.org/x/tools v0.24.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
50
go.sum
Normal file
50
go.sum
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||||
|
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||||
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
|
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
|
github.com/jcobhams/echovalidate/v2 v2.0.3/go.mod h1:I9VVW+j88qwoJC0ugb9B2Olvc2w+RN66oDyrVaT+Gns=
|
||||||
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
|
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||||
|
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/swaggo/echo-swagger v1.4.1/go.mod h1:C8bSi+9yH2FLZsnhqMZLIZddpUxZdBYuNHbtaS1Hljc=
|
||||||
|
github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM=
|
||||||
|
github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
|
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||||
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
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.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
|
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
25
lib/validator/validator.go
Normal file
25
lib/validator/validator.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
validator "github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Validator struct {
|
||||||
|
validator *validator.Validate
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewValidator() *Validator {
|
||||||
|
return &Validator{validator: validator.New()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (val *Validator) Validate(i interface{}) error {
|
||||||
|
err := val.validator.Struct(i)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err = errors.New(strings.Replace(err.Error(), "\n", ", ", -1))
|
||||||
|
return err
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user