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
19 changes: 16 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
include local.env
LOCAL_BIN:=$(CURDIR)/bin

LOCAL_MIGRATION_DIR=$(MIGRATION_DIR)
LOCAL_MIGRATION_DSN="host=localhost port=$(PG_PORT) dbname=$(POSTGRES_DB) user=$(POSTGRES_USER) password=$(POSTGRES_PASSWORD) sslmode=disable"

install-golangci-lint:
GOBIN=$(LOCAL_BIN) go install github.com/golangci/golangci-lint/cmd/[email protected]

lint:
GOBIN=$(LOCAL_BIN) golangci-lint run ./... --config .golangci.pipeline.yaml
GOBIN=$(LOCAL_BIN) $(LOCAL_BIN)/golangci-lint run ./... --config .golangci.pipeline.yaml

install-deps:
GOBIN=$(LOCAL_BIN) go install google.golang.org/protobuf/cmd/[email protected]
GOBIN=$(LOCAL_BIN) go install -mod=mod google.golang.org/grpc/cmd/[email protected]
GOBIN=$(LOCAL_BIN) go install github.com/pressly/goose/v3/cmd/goose@latest

get-deps:
go get -u google.golang.org/protobuf/cmd/protoc-gen-go
go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc


generate:
make generate-chat-api

Expand All @@ -25,4 +29,13 @@ generate-chat-api:
--plugin=protoc-gen-go=bin/protoc-gen-go \
--go-grpc_out=pkg/chat_v1 --go-grpc_opt=paths=source_relative \
--plugin=protoc-gen-go-grpc=bin/protoc-gen-go-grpc \
api/chat_server_v1/chat.proto
api/chat_server_v1/chat.proto

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

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

local-migration-down:
$(LOCAL_BIN)/goose -dir ${LOCAL_MIGRATION_DIR} postgres ${LOCAL_MIGRATION_DSN} down -v
109 changes: 92 additions & 17 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,117 @@ import (
desc "chat_server/pkg/chat_v1"
"context"
"fmt"
"github.com/fatih/color"
"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"
"log"
"net"
)

const grpcPort = 50052
const (
grpcPort = 50052
chatTable = "chat"
chatsToUsersTable = "chats_to_users"
messageTable = "message"
dbDsn = "host=localhost port=54322 dbname=chat-service user=dev_course password=1801 sslmode=disable"
)

type server struct {
desc.UnimplementedChatV1Server
}

func (s *server) Create(_ context.Context, req *desc.CreateChatRequest) (*desc.CreateChatResponse, error) {
fmt.Println("Create request")
fmt.Println(color.GreenString("", req.Usernames))
fmt.Println("========================================")
func (s *server) Create(ctx context.Context, req *desc.CreateChatRequest) (*desc.CreateChatResponse, error) {
if len(req.Usernames) == 0 {
return nil, errors.New("Usernames shouldn't be null")
}

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

insertBuilder := squirrel.Insert(chatTable).
PlaceholderFormat(squirrel.Dollar).
Columns("name").
Values("chat name").
Suffix("RETURNING id")

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

return &desc.CreateChatResponse{Id: 2}, nil
var chatID int64
err = pool.QueryRow(ctx, query, args...).Scan(&chatID)
if err != nil {
return nil, errors.Wrapf(err, "Failed to execute %s", err)
}

for _, v := range req.Usernames {
insertBuider := squirrel.Insert(chatsToUsersTable).
PlaceholderFormat(squirrel.Dollar).
Columns("chatID", "username").
Values(chatID, v)

query, args, err := insertBuider.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 &desc.CreateChatResponse{Id: chatID}, nil
}

func (s *server) Delete(_ context.Context, req *desc.DeleteRequest) (*empty.Empty, error) {
fmt.Println("Delete request")
fmt.Println(color.GreenString("Id", req.Id))
fmt.Println("========================================")
func (s *server) Delete(ctx context.Context, req *desc.DeleteRequest) (*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(chatsToUsersTable).
Where(squirrel.Eq{"chatId": 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 (s *server) SendMessage(_ context.Context, req *desc.SendMessageRequest) (*empty.Empty, error) {
fmt.Println("SendMessage request")
fmt.Println(color.GreenString("From", req.From))
fmt.Println(color.GreenString("Text", req.Text))
fmt.Println(color.GreenString("Timestamp", req.Timestamp))
fmt.Println("========================================")
func (s *server) SendMessage(ctx context.Context, req *desc.SendMessageRequest) (*empty.Empty, error) {
pool, err := pgx.Connect(ctx, dbDsn)
if err != nil {
return nil, errors.Wrapf(err, "Failed to connect to database %s", err)
}

insertBuilder := squirrel.Insert(messageTable).
PlaceholderFormat(squirrel.Dollar).
Columns("\"from\"", "text").
Values(req.From, req.Text)

query, args, err := insertBuilder.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
}

Expand All @@ -54,6 +128,7 @@ func main() {
reflection.Register(s)
desc.RegisterChatV1Server(s, &server{})

fmt.Println("Server has been started")
if err = s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
Expand Down
9 changes: 9 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: '3'

services:
chat-service-db:
image: postgres:14-alpine3.17
env_file:
- "local.env"
ports:
- "54322:5432"
24 changes: 18 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@ module chat_server

go 1.20

require github.com/fatih/color v1.15.0
require (
github.com/Masterminds/squirrel v1.5.4
github.com/golang/protobuf v1.5.3
github.com/jackc/pgx/v4 v4.18.1
github.com/pkg/errors v0.8.1
google.golang.org/grpc v1.58.2
google.golang.org/protobuf v1.31.0
)

require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
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/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/grpc v1.58.2 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
Loading