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
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM golang:1.23.4 AS builder
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

лучше брать образ с нужной версией go - у тебя это go 1.22.0


WORKDIR /app

COPY go.mod go.sum ./

RUN go mod tidy
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

лучше go mod download


COPY . .

RUN go build -o tracker .

FROM debian:bullseye-slim
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

отлично что сделал multistage build


RUN apt-get update && apt-get install -y sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY --from=builder /app/tracker /app/
COPY --from=builder /app/tracker.db /app/

EXPOSE 8080
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это лишнее - приложение не сетевое еще


CMD ["./tracker"]
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
# 42_final
Данный сервис позволяет управлять посылками клиентов, храня их в базе данных SQLite.


# **Основные возможности:**

Регистрация посылки (номер, клиент, статус, адрес, дата регистрации)

Изменение статуса (Registered -> Sent -> Delivered)

Изменение адреса доставки (только для статуса registered)

Получение списка посылок клиента

Удаление посылки (возможно только в статусе registered)


Сервис написан на Go и взаимодействует с базой данных через database/sql.


# **Технологии:**

Go – серверная часть

SQLite – база данных

database/sql – работа с БД

Git – контроль версий

Testify – тестирование

Docker – контейнеризация


# **Покрываемые тесты:**


TestAddGetDelete – проверяет добавление, получение и удаление посылки

TestSetAddress – проверяет обновление адреса

TestSetStatus – проверяет обновление статуса

TestGetByClient – проверяет получение посылок по клиенту
27 changes: 27 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module github.com/Yandex-Practicum/42-docker-final

go 1.22.0

require (
github.com/stretchr/testify v1.8.4
modernc.org/sqlite v1.29.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.16.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.41.0 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
)
47 changes: 47 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA=
modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
177 changes: 177 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package main

import (
"database/sql"
"fmt"
"time"

_ "modernc.org/sqlite"
)

const (
ParcelStatusRegistered = "registered"
ParcelStatusSent = "sent"
ParcelStatusDelivered = "delivered"
)

type Parcel struct {
Number int
Client int
Status string
Address string
CreatedAt string
}

type ParcelService struct {
store ParcelStore
}

func NewParcelService(store ParcelStore) ParcelService {
return ParcelService{store: store}
}

func (s ParcelService) Register(client int, address string) (Parcel, error) {
parcel := Parcel{
Client: client,
Status: ParcelStatusRegistered,
Address: address,
CreatedAt: time.Now().UTC().Format(time.RFC3339),
}

id, err := s.store.Add(parcel)
if err != nil {
return parcel, err
}

parcel.Number = id

fmt.Printf("Новая посылка № %d на адрес %s от клиента с идентификатором %d зарегистрирована %s\n",
parcel.Number, parcel.Address, parcel.Client, parcel.CreatedAt)

return parcel, nil
}

func (s ParcelService) PrintClientParcels(client int) error {
parcels, err := s.store.GetByClient(client)
if err != nil {
return err
}

fmt.Printf("Посылки клиента %d:\n", client)
for _, parcel := range parcels {
fmt.Printf("Посылка № %d на адрес %s от клиента с идентификатором %d зарегистрирована %s, статус %s\n",
parcel.Number, parcel.Address, parcel.Client, parcel.CreatedAt, parcel.Status)
}
fmt.Println()

return nil
}

func (s ParcelService) NextStatus(number int) error {
parcel, err := s.store.Get(number)
if err != nil {
return err
}

var nextStatus string
switch parcel.Status {
case ParcelStatusRegistered:
nextStatus = ParcelStatusSent
case ParcelStatusSent:
nextStatus = ParcelStatusDelivered
case ParcelStatusDelivered:
return nil
}

fmt.Printf("У посылки № %d новый статус: %s\n", number, nextStatus)

return s.store.SetStatus(number, nextStatus)
}

func (s ParcelService) ChangeAddress(number int, address string) error {
return s.store.SetAddress(number, address)
}

func (s ParcelService) Delete(number int) error {
return s.store.Delete(number)
}

func main() {
db, err := sql.Open("sqlite", "tracker.db")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()

store := NewParcelStore(db)
service := NewParcelService(store)

// регистрация посылки
client := 1
address := "Псков, д. Пушкина, ул. Колотушкина, д. 5"
p, err := service.Register(client, address)
if err != nil {
fmt.Println(err)
return
}

// изменение адреса
newAddress := "Саратов, д. Верхние Зори, ул. Козлова, д. 25"
err = service.ChangeAddress(p.Number, newAddress)
if err != nil {
fmt.Println(err)
return
}

// изменение статуса
err = service.NextStatus(p.Number)
if err != nil {
fmt.Println(err)
return
}

// вывод посылок клиента
err = service.PrintClientParcels(client)
if err != nil {
fmt.Println(err)
return
}

// попытка удаления отправленной посылки
err = service.Delete(p.Number)
if err != nil {
fmt.Println(err)
return
}

// вывод посылок клиента
// предыдущая посылка не должна удалиться, т.к. её статус НЕ «зарегистрирована»
err = service.PrintClientParcels(client)
if err != nil {
fmt.Println(err)
return
}

// регистрация новой посылки
p, err = service.Register(client, address)
if err != nil {
fmt.Println(err)
return
}

// удаление новой посылки
err = service.Delete(p.Number)
if err != nil {
fmt.Println(err)
return
}

// вывод посылок клиента
// здесь не должно быть последней посылки, т.к. она должна была успешно удалиться
err = service.PrintClientParcels(client)
if err != nil {
fmt.Println(err)
return
}
}
Loading