test
This commit is contained in:
parent
a0f879a3d4
commit
3c6748d5b3
@ -3,6 +3,6 @@ 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
|
||||
RUN go mod tidy && swag init -g cmd/main.go -o api/http
|
||||
|
||||
CMD go run cmd/main.go
|
@ -1,5 +1,5 @@
|
||||
// Package docs Code generated by swaggo/swag. DO NOT EDIT
|
||||
package docs
|
||||
package http
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
|
30
cmd/main.go
30
cmd/main.go
@ -1,17 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"log/slog"
|
||||
"os"
|
||||
)
|
||||
|
||||
import (
|
||||
_ "donat-widget/cmd/docs"
|
||||
"donat-widget/cmd/handlers"
|
||||
"donat-widget/config"
|
||||
"donat-widget/lib/validator"
|
||||
)
|
||||
import "donat-widget/internal/app/http"
|
||||
|
||||
// @title Widget service
|
||||
// @version 1.0
|
||||
@ -20,20 +9,7 @@ import (
|
||||
// @host localhost:8002
|
||||
// @BasePath /api/widget
|
||||
|
||||
func init() {
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
||||
slog.SetDefault(logger)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := initApp()
|
||||
port := config.Config.Server.Port
|
||||
app.Logger.Fatal(app.Start(":" + port))
|
||||
}
|
||||
|
||||
func initApp() *echo.Echo {
|
||||
app := echo.New()
|
||||
app.Validator = validator.NewValidator()
|
||||
handlers.IncludeRouters(app)
|
||||
return app
|
||||
httpServer := http.NewApp()
|
||||
http.Run(httpServer)
|
||||
}
|
||||
|
@ -2,14 +2,13 @@ package pg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"donat-widget/config"
|
||||
"fmt"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Postgres struct {
|
||||
Db *pgxpool.Pool
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
var (
|
||||
@ -20,7 +19,7 @@ var (
|
||||
func NewPgPool(
|
||||
ctx context.Context,
|
||||
username, password, host, port, dbname string,
|
||||
) (*Postgres, error) {
|
||||
) *Postgres {
|
||||
connString := "postgres://" + username + ":" + password + "@" + host + ":" + port + "/" + dbname + "?pool_max_conns=100"
|
||||
pgOnce.Do(func() {
|
||||
db, err := pgxpool.New(ctx, connString)
|
||||
@ -30,20 +29,11 @@ func NewPgPool(
|
||||
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()
|
||||
return pgInstance
|
||||
}
|
||||
|
||||
func (pg *Postgres) CreateTable(ctx context.Context) error {
|
||||
result, err := pg.Db.Exec(ctx, createTableQuery)
|
||||
result, err := pg.db.Exec(ctx, createTableQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -51,11 +41,32 @@ func (pg *Postgres) CreateTable(ctx context.Context) error {
|
||||
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,
|
||||
)
|
||||
func (pg *Postgres) DropTable(ctx context.Context) error {
|
||||
result, err := pg.db.Exec(ctx, dropTableQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(result)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pg *Postgres) Exec(ctx context.Context, query string, args ...interface{}) (interface{}, error) {
|
||||
result, err := pg.db.Exec(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (pg *Postgres) Query(ctx context.Context, query string, args ...interface{}) (interface{}, error) {
|
||||
result, err := pg.db.Query(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (pg *Postgres) QueryRow(ctx context.Context, query string, args ...interface{}) interface{} {
|
||||
result := pg.db.QueryRow(ctx, query, args...)
|
||||
return result
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ var createTableQuery = `
|
||||
video TEXT DEFAULT '',
|
||||
image TEXT DEFAULT '',
|
||||
audio TEXT DEFAULT '',
|
||||
duration TEXT DEFAULT '',
|
||||
duration INTEGER DEFAULT 30,
|
||||
display BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
@ -32,5 +32,5 @@ CREATE OR REPLACE FUNCTION update_updated_at()
|
||||
`
|
||||
|
||||
var dropTableQuery = `
|
||||
DROP TABLE IF EXISTS test_users;
|
||||
DROP TABLE IF EXISTS widgets;
|
||||
`
|
||||
|
@ -1 +1,52 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/labstack/echo/v4"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type requestModel struct {
|
||||
UserId int `json:"userId" validate:"required"`
|
||||
}
|
||||
|
||||
type responseModel struct {
|
||||
WidgetId int `json:"widgetId"`
|
||||
}
|
||||
|
||||
type Creator interface {
|
||||
Create(ctx context.Context, userId int) (int, error)
|
||||
}
|
||||
|
||||
// Create @Description Create widget
|
||||
//
|
||||
// @Tags Widget
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param RegisterData body requestModel true "Create widget"
|
||||
// @Success 200 {object} responseModel
|
||||
// @Router /api/widget/create [post]
|
||||
func Create(service Creator, log *slog.Logger) echo.HandlerFunc {
|
||||
return func(request echo.Context) error {
|
||||
ctx := context.Background()
|
||||
var widgetData requestModel
|
||||
if err := request.Bind(&widgetData); err != nil {
|
||||
slog.Error(err.Error())
|
||||
return echo.NewHTTPError(400, err.Error())
|
||||
}
|
||||
|
||||
err := request.Validate(&widgetData)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
return echo.NewHTTPError(400, err.Error())
|
||||
}
|
||||
|
||||
id, err := service.Create(ctx, widgetData.UserId)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
return request.JSON(422, err)
|
||||
}
|
||||
return request.String(200, strconv.FormatUint(uint64(id), 10))
|
||||
}
|
||||
}
|
||||
|
73
internal/app/http/app.go
Normal file
73
internal/app/http/app.go
Normal file
@ -0,0 +1,73 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "donat-widget/api/http"
|
||||
"donat-widget/infrastructure/pg"
|
||||
widgetHandler "donat-widget/internal/api/http/handlers/widget"
|
||||
"donat-widget/internal/config"
|
||||
"donat-widget/pkg/validator"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/swaggo/echo-swagger"
|
||||
"log/slog"
|
||||
"os"
|
||||
)
|
||||
|
||||
import (
|
||||
widgetService "donat-widget/internal/service/widget"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
func NewApp() *echo.Echo {
|
||||
app := &App{}
|
||||
cfg := app.InitConfig()
|
||||
pool := app.initDB(cfg)
|
||||
log := app.InitLogger()
|
||||
|
||||
server := InitHTTPServer()
|
||||
InitHandlers(server, pool, log)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func Run(server *echo.Echo) {
|
||||
server.Logger.Fatal(server.Start(":8002"))
|
||||
}
|
||||
|
||||
func InitHTTPServer() *echo.Echo {
|
||||
server := echo.New()
|
||||
server.Validator = validator.NewValidator()
|
||||
return server
|
||||
}
|
||||
|
||||
func (a *App) InitConfig() *config.Config {
|
||||
cfg := config.Init()
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (a *App) initDB(cfg *config.Config) *pg.Postgres {
|
||||
pool := pg.NewPgPool(
|
||||
context.Background(),
|
||||
cfg.Database.Username,
|
||||
cfg.Database.Password,
|
||||
cfg.Database.Host,
|
||||
cfg.Database.Port,
|
||||
cfg.Database.DBName,
|
||||
)
|
||||
return pool
|
||||
}
|
||||
|
||||
func InitHandlers(server *echo.Echo, pool *pg.Postgres, log *slog.Logger) {
|
||||
PREFIX := "/api/widget"
|
||||
server.GET("/api/docs/*", echoSwagger.WrapHandler)
|
||||
widgetSvc := widgetService.New(pool)
|
||||
server.GET(PREFIX+"/create", widgetHandler.Create(widgetSvc, log))
|
||||
}
|
||||
|
||||
func (a *App) InitLogger() *slog.Logger {
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
||||
return logger
|
||||
}
|
@ -1 +1,33 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v2"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config 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"`
|
||||
}
|
||||
|
||||
func Init() *Config {
|
||||
data, err := os.ReadFile("internal/config/config.yaml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var cfg Config
|
||||
|
||||
err = yaml.Unmarshal(data, &cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &cfg
|
||||
}
|
||||
|
@ -1 +1,32 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id int `json:"id"`
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
func (r *Repository) Create(
|
||||
ctx context.Context,
|
||||
userId int,
|
||||
) (int, error) {
|
||||
query := `
|
||||
INSERT INTO widgets (userId)
|
||||
VALUES (@userId);
|
||||
`
|
||||
args := pgx.NamedArgs{
|
||||
"userId": userId,
|
||||
}
|
||||
result, err := r.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
widgetId := 9
|
||||
fmt.Println(result)
|
||||
return widgetId, nil
|
||||
}
|
||||
|
19
internal/repository/widget/init.go
Normal file
19
internal/repository/widget/init.go
Normal file
@ -0,0 +1,19 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Pool interface {
|
||||
Exec(ctx context.Context, query string, args ...interface{}) (interface{}, error)
|
||||
Query(ctx context.Context, query string, args ...interface{}) (interface{}, error)
|
||||
QueryRow(ctx context.Context, query string, args ...interface{}) interface{}
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
Pool
|
||||
}
|
||||
|
||||
func New(pool Pool) *Repository {
|
||||
return &Repository{pool}
|
||||
}
|
@ -1 +1,17 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type CreatorRepository interface {
|
||||
Create(ctx context.Context, userId int) (int, error)
|
||||
}
|
||||
|
||||
func (service *Service) Create(ctx context.Context, userId int) (int, error) {
|
||||
widgetId, err := service.repository.Create(ctx, userId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return widgetId, nil
|
||||
}
|
||||
|
@ -1 +1,16 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"donat-widget/infrastructure/pg"
|
||||
)
|
||||
|
||||
type Deleter interface {
|
||||
Delete(ctx context.Context) (int, error)
|
||||
}
|
||||
|
||||
func DeleteWidget(pool *pg.Postgres) func(ctx context.Context, repository Deleter) int {
|
||||
return func(ctx context.Context, repository Deleter) int {
|
||||
return 8
|
||||
}
|
||||
}
|
||||
|
19
internal/service/widget/init.go
Normal file
19
internal/service/widget/init.go
Normal file
@ -0,0 +1,19 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
widgetRepository "donat-widget/internal/repository/widget"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(ctx context.Context, userId int) (int, error)
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
repository Repository
|
||||
}
|
||||
|
||||
func New(pool widgetRepository.Pool) *Service {
|
||||
repository := widgetRepository.New(pool)
|
||||
return &Service{repository: repository}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user