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
57 changes: 16 additions & 41 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,13 @@ func (s ParcelService) Register(client int, address string) (Parcel, error) {
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
}

Expand All @@ -56,14 +52,12 @@ func (s ParcelService) PrintClientParcels(client int) error {
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
}

Expand All @@ -72,19 +66,16 @@ func (s ParcelService) NextStatus(number int) error {
if err != nil {
return err
}

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

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

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

Expand All @@ -97,12 +88,15 @@ func (s ParcelService) Delete(number int) error {
}

func main() {
// настройте подключение к БД

store := // создайте объект ParcelStore функцией NewParcelStore
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)
Expand All @@ -111,62 +105,43 @@ func main() {
return
}

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

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

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

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

// вывод посылок клиента
// предыдущая посылка не должна удалиться, т.к. её статус НЕ «зарегистрирована»
err = service.PrintClientParcels(client)
if err != nil {
if err := service.PrintClientParcels(client); 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 {
if err := service.Delete(p.Number); err != nil {
fmt.Println(err)
return
}

// вывод посылок клиента
// здесь не должно быть последней посылки, т.к. она должна была успешно удалиться
err = service.PrintClientParcels(client)
if err != nil {
if err := service.PrintClientParcels(client); err != nil {
fmt.Println(err)
return
}
}
105 changes: 82 additions & 23 deletions parcel.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,118 @@ package main

import (
"database/sql"
"fmt"
)

type ParcelStore struct {
db *sql.DB
}

func NewParcelStore(db *sql.DB) ParcelStore {
_, _ = db.Exec(`CREATE TABLE IF NOT EXISTS parcel(
number INTEGER PRIMARY KEY AUTOINCREMENT,
client INTEGER NOT NULL,
status TEXT NOT NULL,
address TEXT NOT NULL,
created_at TEXT NOT NULL
)`)
return ParcelStore{db: db}
}

func (s ParcelStore) Add(p Parcel) (int, error) {
// реализуйте добавление строки в таблицу parcel, используйте данные из переменной p

// верните идентификатор последней добавленной записи
return 0, nil
res, err := s.db.Exec(
`INSERT INTO parcel(client,status,address,created_at) VALUES(?,?,?,?)`,
p.Client, p.Status, p.Address, p.CreatedAt,
)
if err != nil {
return 0, err
}
id, err := res.LastInsertId()
return int(id), err
}

func (s ParcelStore) Get(number int) (Parcel, error) {
// реализуйте чтение строки по заданному number
// здесь из таблицы должна вернуться только одна строка

// заполните объект Parcel данными из таблицы
p := Parcel{}

row := s.db.QueryRow(
`SELECT number,client,status,address,created_at FROM parcel WHERE number=?`,
number,
)
var p Parcel
if err := row.Scan(&p.Number, &p.Client, &p.Status, &p.Address, &p.CreatedAt); err != nil {
return p, err
}
return p, nil
}

func (s ParcelStore) GetByClient(client int) ([]Parcel, error) {
// реализуйте чтение строк из таблицы parcel по заданному client
// здесь из таблицы может вернуться несколько строк

// заполните срез Parcel данными из таблицы
rows, err := s.db.Query(
`SELECT number,client,status,address,created_at FROM parcel WHERE client=?`,
client,
)
if err != nil {
return nil, err
}
defer rows.Close()
var res []Parcel

for rows.Next() {
var p Parcel
if err := rows.Scan(&p.Number, &p.Client, &p.Status, &p.Address, &p.CreatedAt); err != nil {
return nil, err
}
res = append(res, p)
}
if err := rows.Err(); err != nil {
return nil, err
}
return res, nil
}

func (s ParcelStore) SetStatus(number int, status string) error {
// реализуйте обновление статуса в таблице parcel

res, err := s.db.Exec(`UPDATE parcel SET status=? WHERE number=?`, status, number)
if err != nil {
return err
}
aff, err := res.RowsAffected()
if err != nil {
return err
}
if aff == 0 {
return fmt.Errorf("parcel %d not found", number)
}
return nil
}

func (s ParcelStore) SetAddress(number int, address string) error {
// реализуйте обновление адреса в таблице parcel
// менять адрес можно только если значение статуса registered

res, err := s.db.Exec(
`UPDATE parcel SET address=? WHERE number=? AND status=?`,
address, number, ParcelStatusRegistered,
)
if err != nil {
return err
}
aff, err := res.RowsAffected()
if err != nil {
return err
}
if aff == 0 {
return fmt.Errorf("cannot change address")
}
return nil
}

func (s ParcelStore) Delete(number int) error {
// реализуйте удаление строки из таблицы parcel
// удалять строку можно только если значение статуса registered

res, err := s.db.Exec(
`DELETE FROM parcel WHERE number=? AND status=?`,
number, ParcelStatusRegistered,
)
if err != nil {
return err
}
aff, err := res.RowsAffected()
if err != nil {
return err
}
if aff == 0 {
return fmt.Errorf("cannot delete parcel")
}
return nil
}
Loading