mirror of
https://github.com/3ybactuk/marketplace-go-service-project.git
synced 2025-12-21 10:19:04 +03:00
[hw-4] add postgres db
This commit is contained in:
32
loms/internal/domain/repository/stocks/sqlc/db.go
Normal file
32
loms/internal/domain/repository/stocks/sqlc/db.go
Normal 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,
|
||||
}
|
||||
}
|
||||
11
loms/internal/domain/repository/stocks/sqlc/models.go
Normal file
11
loms/internal/domain/repository/stocks/sqlc/models.go
Normal 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
|
||||
}
|
||||
18
loms/internal/domain/repository/stocks/sqlc/querier.go
Normal file
18
loms/internal/domain/repository/stocks/sqlc/querier.go
Normal 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)
|
||||
24
loms/internal/domain/repository/stocks/sqlc/query.sql
Normal file
24
loms/internal/domain/repository/stocks/sqlc/query.sql
Normal 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;
|
||||
85
loms/internal/domain/repository/stocks/sqlc/query.sql.go
Normal file
85
loms/internal/domain/repository/stocks/sqlc/query.sql.go
Normal 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
|
||||
}
|
||||
137
loms/internal/domain/repository/stocks/sqlc/repository.go
Normal file
137
loms/internal/domain/repository/stocks/sqlc/repository.go
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user