add create budget route
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
866009cf09
commit
bf85f31056
|
@ -9,6 +9,7 @@ import (
|
|||
"os"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/app"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/budget"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/user"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
|
@ -38,6 +39,7 @@ func main() {
|
|||
|
||||
categoryService := category.NewCategoryService(dbpool)
|
||||
userService := user.NewUserService(dbpool)
|
||||
budgetService := budget.NewBudgetService(dbpool)
|
||||
|
||||
// Create a gRPC server object
|
||||
s := grpc.NewServer(
|
||||
|
@ -61,7 +63,14 @@ func main() {
|
|||
),
|
||||
)
|
||||
// Attach the Greeter service to the server
|
||||
proto.RegisterSmmCoreServer(s, app.NewServer(categoryService, userService))
|
||||
proto.RegisterSmmCoreServer(
|
||||
s,
|
||||
app.NewServer(
|
||||
categoryService,
|
||||
userService,
|
||||
budgetService,
|
||||
),
|
||||
)
|
||||
// Serve gRPC server
|
||||
log.Println("Serving gRPC on 0.0.0.0:8080")
|
||||
go func() {
|
||||
|
|
|
@ -3,6 +3,7 @@ package app
|
|||
import (
|
||||
"context"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/budget"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/user"
|
||||
proto "git.3crabs.ru/save_my_money/smm_core/proto"
|
||||
|
@ -12,15 +13,18 @@ type Server struct {
|
|||
proto.UnsafeSmmCoreServer
|
||||
categoryService *category.CategoryService
|
||||
userService *user.UserService
|
||||
budgetService *budget.BudgetService
|
||||
}
|
||||
|
||||
func NewServer(
|
||||
categoryService *category.CategoryService,
|
||||
userService *user.UserService,
|
||||
budgetService *budget.BudgetService,
|
||||
) proto.SmmCoreServer {
|
||||
return &Server{
|
||||
categoryService: categoryService,
|
||||
userService: userService,
|
||||
budgetService: budgetService,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,9 +66,24 @@ func (s *Server) Login(ctx context.Context, req *proto.LoginReq) (*proto.User, e
|
|||
}, nil
|
||||
}
|
||||
|
||||
// AddBudget implements proto.SmmCoreServer.
|
||||
func (s *Server) AddBudget(context.Context, *proto.AddBudgetReq) (*proto.Budget, error) {
|
||||
panic("unimplemented")
|
||||
func (s *Server) AddBudget(ctx context.Context, req *proto.AddBudgetReq) (*proto.Budget, error) {
|
||||
budget, err := s.budgetService.AddBudget(
|
||||
ctx,
|
||||
&budget.BudgetEntity{
|
||||
Name: req.Name,
|
||||
StartDay: int(req.StartDay),
|
||||
MonthlyLimit: int(req.MonthlyLimit),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.Budget{
|
||||
Id: int32(budget.Id),
|
||||
Name: budget.Name,
|
||||
StartDay: int32(budget.StartDay),
|
||||
MonthlyLimit: int32(budget.MonthlyLimit),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AddCategory implements proto.SmmCoreServer.
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package budget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/context_utils"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type BudgetEntity struct {
|
||||
Id int
|
||||
Name string
|
||||
StartDay int
|
||||
MonthlyLimit int
|
||||
}
|
||||
|
||||
type BudgetService struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewBudgetService(
|
||||
db *pgxpool.Pool,
|
||||
) *BudgetService {
|
||||
return &BudgetService{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BudgetService) AddBudget(ctx context.Context, budget *BudgetEntity) (*BudgetEntity, error) {
|
||||
userId, err := context_utils.GetUserId(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx, err := s.db.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
query := `INSERT INTO budgets (name, start_day, monthly_limit) VALUES (@name, @start_day, @monthly_limit) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"name": budget.Name,
|
||||
"start_day": budget.StartDay,
|
||||
"monthly_limit": budget.MonthlyLimit,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&budget.Id); err != nil {
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
|
||||
query = `INSERT INTO users_budgets (user_id, budget_id) VALUES (@user_id, @budget_id) RETURNING id`
|
||||
args = pgx.NamedArgs{
|
||||
"user_id": userId,
|
||||
"budget_id": budget.Id,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&budget.Id); err != nil {
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
|
||||
if err = tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return budget, nil
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS users (
|
|||
id SERIAL PRIMARY KEY,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
created_at TIMESTAMP
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS budgets (
|
|||
name TEXT NOT NULL,
|
||||
start_day INT NOT NULL,
|
||||
monthly_limit INT DEFAULT 0,
|
||||
created_at TIMESTAMP
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS categories (
|
|||
favorite BOOLEAN DEFAULT FALSE,
|
||||
monthly_limit INT DEFAULT 0,
|
||||
UNIQUE (budget_id, name),
|
||||
created_at TIMESTAMP
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS wastes (
|
|||
amount FLOAT NOT NULL,
|
||||
budget_id INT REFERENCES budgets(id) ON DELETE CASCADE,
|
||||
category_id INT REFERENCES categories(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS users_budgets (
|
|||
id SERIAL PRIMARY KEY,
|
||||
user_id INT REFERENCES users(id) ON DELETE CASCADE,
|
||||
budget_id INT REFERENCES budgets(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
|
Loading…
Reference in New Issue