Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ build:
GOOS=linux GOARCH=amd64 go build -o bin/main cmd/main.go

local-migration-status:
$(LOCAL_BIN)/goose -dir ${LOCAL_MIGRATION_DIR} postgres ${LOCAL_MIGRATION_DSN} status -v
$(LOCAL_BIN)/goose -dir ${MIGRATION_DR} postgres ${PG_DSN} status -v

local-migration-up:
$(LOCAL_BIN)/goose -dir ${LOCAL_MIGRATION_DIR} postgres ${LOCAL_MIGRATION_DSN} up -v
$(LOCAL_BIN)/goose -dir ${MIGRATION_DR} postgres ${PG_DSN} up -v

local-migration-down:
$(LOCAL_BIN)/goose -dir ${LOCAL_MIGRATION_DIR} postgres ${LOCAL_MIGRATION_DSN} down -v
$(LOCAL_BIN)/goose -dir ${MIGRATION_DR} postgres ${PG_DSN} down -v


copy-to-server:
Expand Down
166 changes: 7 additions & 159 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,172 +1,20 @@
package main

import (
desc "auth/pkg/user_v1"
"auth/internal/app"
"context"
"fmt"
"github.com/Masterminds/squirrel"
"github.com/golang/protobuf/ptypes/empty"
"github.com/jackc/pgx/v4"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/types/known/timestamppb"
"log"
"net"
"time"
)

const grpcPort = 50051
const dbDSN = "host=localhost port=54321 dbname=auth-service user=dev-course password=1801 sslmode=disable"

type server struct {
desc.UnimplementedUserV1Server
}

func (s *server) Create(ctx context.Context, req *desc.CreateUserRequest) (*desc.CreateUserResponse, error) {
if req.User.Password != req.User.PasswordConfirm {
return nil, errors.New("Passwords are not equal")
}

pool, err := pgx.Connect(ctx, dbDSN)
if err != nil {
return nil, errors.Wrapf(err, "Failed to connect to database %s", err)
}

insertBuilder := squirrel.Insert("\"user\"").
PlaceholderFormat(squirrel.Dollar).
Columns("name", "email", "role", "password").
Values(req.User.Name, req.User.Email, req.User.Role.String(), req.User.Password).
Suffix("RETURNING id")

query, args, err := insertBuilder.ToSql()
if err != nil {
return nil, errors.Wrapf(err, "Failed to build query %s", err)
}

var id int64
err = pool.QueryRow(ctx, query, args...).Scan(&id)
if err != nil {
return nil, errors.Wrapf(err, "Failed to make query: %s", err)
}

return &desc.CreateUserResponse{
Id: id,
}, nil
}

func (s *server) Get(ctx context.Context, req *desc.GetUserRequest) (*desc.GetUserResponse, error) {
pool, err := pgx.Connect(ctx, dbDSN)
if err != nil {
return nil, errors.Wrapf(err, "Failed to connect to database %s", err)
}

selectBuilder := squirrel.Select("id", "name", "email", "role", "created_at", "updated_at").
PlaceholderFormat(squirrel.Dollar).
From("\"user\"").
Where(squirrel.Eq{"id": req.Id})

query, args, err := selectBuilder.ToSql()
if err != nil {
return nil, errors.Wrapf(err, "Failed to build query %s", err)
}

var userId int64
var userName string
var email string
var role string
var createdAt time.Time
var updatedAt *time.Time
err = pool.QueryRow(ctx, query, args...).Scan(&userId, &userName, &email, &role, &createdAt, &updatedAt)
if err != nil {
return nil, errors.Wrapf(err, "Failed to make query: %s", err)
}

user := &desc.GetUserResponse{
Id: userId,
Name: userName,
Email: email,
Role: desc.Role(desc.Role_value[role]),
CreatedAt: timestamppb.New(createdAt),
}
if updatedAt != nil {
user.UpdatedAt = timestamppb.New(*updatedAt)
}

return user, nil
}

func (s *server) Update(ctx context.Context, req *desc.UpdateUserRequest) (*empty.Empty, error) {
if req.Email == nil && req.Name == nil && req.Role.Number() == 0 {
return &empty.Empty{}, nil
}

pool, err := pgx.Connect(ctx, dbDSN)
if err != nil {
return nil, errors.Wrapf(err, "Failed to connect to database %s", err)
}

builderUpdate := squirrel.Update("\"user\"").
PlaceholderFormat(squirrel.Dollar).
Set("updated_at", time.Now())
if req.Email != nil {
builderUpdate = builderUpdate.Set("email", req.Email.Value)
}
if req.Name != nil {
builderUpdate = builderUpdate.Set("name", req.Name.Value)
}
if req.Role.Number() != 0 {
builderUpdate = builderUpdate.Set("role", req.Role.String())
}
builderUpdate = builderUpdate.Where(squirrel.Eq{"id": req.Id})

query, args, err := builderUpdate.ToSql()
if err != nil {
return nil, errors.Wrapf(err, "Failed to build query: %s", err)
}

_, err = pool.Exec(ctx, query, args...)
if err != nil {
return nil, errors.Wrapf(err, "Failed to executed query: %s", err)
}

return &empty.Empty{}, nil
}

func (s *server) Delete(ctx context.Context, req *desc.DeleteUserRequest) (*empty.Empty, error) {
pool, err := pgx.Connect(ctx, dbDSN)
if err != nil {
return nil, errors.Wrapf(err, "Failed to connect to database %s", err)
}

deleteBuilder := squirrel.Delete("\"user\"").
PlaceholderFormat(squirrel.Dollar).
Where(squirrel.Eq{"id": req.Id})

query, args, err := deleteBuilder.ToSql()
if err != nil {
return nil, errors.Wrapf(err, "Failed to build query %s", err)
}
_, err = pool.Exec(ctx, query, args...)
if err != nil {
return nil, errors.Wrapf(err, "Failed to execute %s", err)
}

return &empty.Empty{}, nil
}

func main() {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
ctx := context.Background()
a, err := app.NewApp(ctx)
if err != nil {
log.Fatalf("failed to listen: %v", err)
log.Fatalf("failed to create new app: %s", err.Error())
}

s := grpc.NewServer()
reflection.Register(s)
desc.RegisterUserV1Server(s, &server{})

fmt.Println("Server has been started")
if err = s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
err = a.Run()
if err != nil {
log.Fatalf("failed to run app: %s", err.Error())
}
}
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@ go 1.20

require (
github.com/Masterminds/squirrel v1.5.4
github.com/georgysavva/scany v1.2.1
github.com/jackc/pgconn v1.14.0
github.com/jackc/pgx/v4 v4.18.1
github.com/pkg/errors v0.8.1
github.com/joho/godotenv v1.5.1
github.com/pkg/errors v0.9.1
google.golang.org/grpc v1.57.0
google.golang.org/protobuf v1.31.0
)

require (
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.0 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/puddle v1.3.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
golang.org/x/crypto v0.6.0 // indirect
Expand Down
Loading