[hw-4] add postgres db

This commit is contained in:
Никита Шубин
2025-06-26 12:08:46 +00:00
parent 3ebaad5558
commit 77ed9fcf85
46 changed files with 1582 additions and 369 deletions

View File

@@ -0,0 +1,32 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
package sqlc
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
}
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,
}
}

View File

@@ -0,0 +1,11 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
package sqlc
type Stock struct {
Sku int64
TotalCount int64
Reserved int64
}

View File

@@ -0,0 +1,18 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
package sqlc
import (
"context"
)
type Querier interface {
StockCancel(ctx context.Context, arg *StockCancelParams) (int64, error)
StockGetByID(ctx context.Context, sku int64) (*Stock, error)
StockReserve(ctx context.Context, arg *StockReserveParams) (int64, error)
StockReserveRemove(ctx context.Context, arg *StockReserveRemoveParams) (int64, error)
}
var _ Querier = (*Queries)(nil)

View File

@@ -0,0 +1,24 @@
-- name: StockGetByID :one
select sku, total_count, reserved
from stocks
where sku = $1
limit 1;
-- name: StockReserve :execrows
update stocks
set reserved = reserved + $2
where sku = $1
and total_count >= reserved + $2;
-- name: StockReserveRemove :execrows
update stocks
set reserved = reserved - $2,
total_count = total_count - $2
where sku = $1
and reserved >= $2 and total_count >= $2;
-- name: StockCancel :execrows
update stocks
set reserved = reserved - $2
where sku = $1
and reserved >= $2;

View File

@@ -0,0 +1,85 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: query.sql
package sqlc
import (
"context"
)
const stockCancel = `-- name: StockCancel :execrows
update stocks
set reserved = reserved - $2
where sku = $1
and reserved >= $2
`
type StockCancelParams struct {
Sku int64
Reserved int64
}
func (q *Queries) StockCancel(ctx context.Context, arg *StockCancelParams) (int64, error) {
result, err := q.db.Exec(ctx, stockCancel, arg.Sku, arg.Reserved)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const stockGetByID = `-- name: StockGetByID :one
select sku, total_count, reserved
from stocks
where sku = $1
limit 1
`
func (q *Queries) StockGetByID(ctx context.Context, sku int64) (*Stock, error) {
row := q.db.QueryRow(ctx, stockGetByID, sku)
var i Stock
err := row.Scan(&i.Sku, &i.TotalCount, &i.Reserved)
return &i, err
}
const stockReserve = `-- name: StockReserve :execrows
update stocks
set reserved = reserved + $2
where sku = $1
and total_count >= reserved + $2
`
type StockReserveParams struct {
Sku int64
Reserved int64
}
func (q *Queries) StockReserve(ctx context.Context, arg *StockReserveParams) (int64, error) {
result, err := q.db.Exec(ctx, stockReserve, arg.Sku, arg.Reserved)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const stockReserveRemove = `-- name: StockReserveRemove :execrows
update stocks
set reserved = reserved - $2,
total_count = total_count - $2
where sku = $1
and reserved >= $2 and total_count >= $2
`
type StockReserveRemoveParams struct {
Sku int64
Reserved int64
}
func (q *Queries) StockReserveRemove(ctx context.Context, arg *StockReserveRemoveParams) (int64, error) {
result, err := q.db.Exec(ctx, stockReserveRemove, arg.Sku, arg.Reserved)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}

View File

@@ -0,0 +1,137 @@
package sqlc
import (
"context"
"errors"
"fmt"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"route256/loms/internal/domain/entity"
"route256/loms/internal/domain/model"
"route256/loms/internal/domain/service"
"route256/loms/internal/infra/postgres"
"route256/loms/internal/infra/tools"
)
type stockRepo struct {
read *pgxpool.Pool
write *pgxpool.Pool
}
func NewStockRepository(write, read *pgxpool.Pool) service.StockRepository {
return &stockRepo{
read: read,
write: write,
}
}
func (s *stockRepo) GetQuerier(ctx context.Context) *Queries {
tx, ok := postgres.TxFromCtx(ctx)
if ok {
return New(tx)
}
return New(s.write)
}
func (s *stockRepo) StockReserve(ctx context.Context, stock *entity.Stock) error {
querier := s.GetQuerier(ctx)
rows, err := querier.StockReserve(ctx, &StockReserveParams{
Sku: int64(stock.Item.ID),
Reserved: int64(stock.Reserved),
})
if err != nil {
return fmt.Errorf("querier.StockReserve: %w", err)
}
if rows == 0 {
return model.ErrNotEnoughStocks
}
return nil
}
func (s *stockRepo) StockReserveRemove(ctx context.Context, stock *entity.Stock) error {
querier := s.GetQuerier(ctx)
rows, err := querier.StockReserveRemove(ctx, &StockReserveRemoveParams{
Sku: int64(stock.Item.ID),
Reserved: int64(stock.Reserved),
})
if err != nil {
return fmt.Errorf("querier.StockReserveRemove: %w", err)
}
if rows > 0 {
return nil
}
_, err = querier.StockGetByID(ctx, int64(stock.Item.ID))
switch {
case errors.Is(err, pgx.ErrNoRows):
return model.ErrUnknownStock
case err != nil:
return fmt.Errorf("querier.StockGetByID: %w", err)
default:
return model.ErrNotEnoughStocks
}
}
func (s *stockRepo) StockCancel(ctx context.Context, stock *entity.Stock) error {
querier := s.GetQuerier(ctx)
rows, err := querier.StockCancel(ctx, &StockCancelParams{
Sku: int64(stock.Item.ID),
Reserved: int64(stock.Reserved),
})
if err != nil {
return fmt.Errorf("querier.StockCancel: %w", err)
}
if rows > 0 {
return nil
}
_, err = querier.StockGetByID(ctx, int64(stock.Item.ID))
switch {
case errors.Is(err, pgx.ErrNoRows):
return model.ErrUnknownStock
case err != nil:
return fmt.Errorf("querier.StockGetByID: %w", err)
default:
return model.ErrNotEnoughStocks
}
}
func (s *stockRepo) StockGetByID(ctx context.Context, sku entity.Sku) (*entity.Stock, error) {
querier := s.GetQuerier(ctx)
stock, err := querier.StockGetByID(ctx, int64(sku))
switch {
case errors.Is(err, pgx.ErrNoRows):
return nil, model.ErrUnknownStock
case err != nil:
return nil, fmt.Errorf("querier.StockGetByID: %w", err)
default:
count, castErr := tools.SafeCastInt64ToUInt32(stock.TotalCount)
if castErr != nil {
return nil, castErr
}
reserved, castErr := tools.SafeCastInt64ToUInt32(stock.Reserved)
if castErr != nil {
return nil, castErr
}
return &entity.Stock{
Item: entity.OrderItem{
ID: entity.Sku(stock.Sku),
Count: count,
},
Reserved: reserved,
}, nil
}
}