Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

добавление логики БД и тестов #133

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
10 changes: 8 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,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)

// регистрация посылки
Expand Down
96 changes: 80 additions & 16 deletions parcel.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,113 @@ func NewParcelStore(db *sql.DB) ParcelStore {
return ParcelStore{db: db}
}

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

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

id, err := res.LastInsertId()
if err != nil {
return 0, err
}

return int(id), nil
}

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

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

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

return p, err
}

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

// заполните срез Parcel данными из таблицы
var res []Parcel

rows, err := s.db.Query("SELECT number, address, client, created_at, status FROM parcel WHERE client = ?", client)
if err != nil {
return nil, err
}
defer rows.Close()

for rows.Next() {

p := Parcel{}

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

// Проверка ошибок после завершения итерации
if err := rows.Err(); err != nil {
return nil, err
}

return res, nil
}

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

return nil
_, err := s.db.Exec("UPDATE parcel SET status = :status WHERE number = :number",
sql.Named("status", status),
sql.Named("number", number))

return err
}

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

p, err := s.Get(number)
if err != nil {
return err
}

// менять адрес можно только если значение статуса registered
if p.Status != ParcelStatusRegistered {
return err
}

return nil
_, err = s.db.Exec("UPDATE parcel SET address = :address WHERE number = :number",
sql.Named("address", address),
sql.Named("number", number))

return err
}

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

p, err := s.Get(number)
if err != nil {
return err
}

// удалять строку можно только если значение статуса registered
if p.Status != ParcelStatusRegistered {
return err
}

return nil
_, err = s.db.Exec("DELETE FROM parcel WHERE number = :number", sql.Named("number", number))
return err
}
70 changes: 64 additions & 6 deletions parcel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,57 +31,104 @@ func getTestParcel() Parcel {
// TestAddGetDelete проверяет добавление, получение и удаление посылки
func TestAddGetDelete(t *testing.T) {
// prepare
db, err := // настройте подключение к БД
db, err := sql.Open("sqlite", "tracker.db") // настройте подключение к БД
require.NoError(t, err)

defer db.Close()
store := NewParcelStore(db)
parcel := getTestParcel()

// add
// добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора
p, err := store.Add(parcel)
require.NoError(t, err)
require.NotEmpty(t, p)

// get
// получите только что добавленную посылку, убедитесь в отсутствии ошибки
// проверьте, что значения всех полей в полученном объекте совпадают со значениями полей в переменной parcel
g, err := store.Get(p)
require.NoError(t, err)
require.Equal(t, g.Address, parcel.Address)
require.Equal(t, g.Client, parcel.Client)
require.Equal(t, g.CreatedAt, parcel.CreatedAt)
require.Equal(t, g.Status, parcel.Status)

// delete
// удалите добавленную посылку, убедитесь в отсутствии ошибки
// проверьте, что посылку больше нельзя получить из БД
err = store.Delete(p)
require.NoError(t, err)

g, err = store.Get(p)
require.Error(t, err)
require.ErrorIs(t, err, sql.ErrNoRows)
require.Empty(t, g)
}

// TestSetAddress проверяет обновление адреса
func TestSetAddress(t *testing.T) {
// prepare
db, err := // настройте подключение к БД
db, err := sql.Open("sqlite", "tracker.db") // настройте подключение к БД
require.NoError(t, err)
defer db.Close()
store := NewParcelStore(db)
parcel := getTestParcel()

// add
// добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора
number, err := store.Add(parcel)
require.NoError(t, err)
require.NotEmpty(t, number)

// set address
// обновите адрес, убедитесь в отсутствии ошибки
newAddress := "new test address"
err = store.SetAddress(number, newAddress)
require.NoError(t, err)

// check
// получите добавленную посылку и убедитесь, что адрес обновился
g, err := store.Get(number)
require.NoError(t, err)
require.Equal(t, g.Address, newAddress)
}

// TestSetStatus проверяет обновление статуса
func TestSetStatus(t *testing.T) {
// prepare
db, err := // настройте подключение к БД
db, err := sql.Open("sqlite", "tracker.db") // настройте подключение к БД
require.NoError(t, err)
defer db.Close()
store := NewParcelStore(db)
parcel := getTestParcel()

// add
// добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора
number, err := store.Add(parcel)
require.NoError(t, err)
require.NotEmpty(t, number)

// set status
// обновите статус, убедитесь в отсутствии ошибки
newStatus := "new status"
err = store.SetStatus(number, newStatus)
require.NoError(t, err)

// check
// получите добавленную посылку и убедитесь, что статус обновился
g, err := store.Get(number)
require.NoError(t, err)
require.Equal(t, g.Status, newStatus)
}

// TestGetByClient проверяет получение посылок по идентификатору клиента
func TestGetByClient(t *testing.T) {
// prepare
db, err := // настройте подключение к БД
db, err := sql.Open("sqlite", "tracker.db") // настройте подключение к БД
require.NoError(t, err)
defer db.Close()
store := NewParcelStore(db)

parcels := []Parcel{
getTestParcel(),
Expand All @@ -98,7 +145,10 @@ func TestGetByClient(t *testing.T) {

// add
for i := 0; i < len(parcels); i++ {
id, err := // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора

id, err := store.Add(parcels[i])
require.NoError(t, err)
require.NotEmpty(t, id)

// обновляем идентификатор добавленной у посылки
parcels[i].Number = id
Expand All @@ -108,14 +158,22 @@ func TestGetByClient(t *testing.T) {
}

// get by client
storedParcels, err := // получите список посылок по идентификатору клиента, сохранённого в переменной client
// убедитесь в отсутствии ошибки
// убедитесь, что количество полученных посылок совпадает с количеством добавленных
storedParcels, err := store.GetByClient(client)
require.NoError(t, err)
require.Len(t, storedParcels, len(parcels))

// check
for _, parcel := range storedParcels {
// в parcelMap лежат добавленные посылки, ключ - идентификатор посылки, значение - сама посылка
// убедитесь, что все посылки из storedParcels есть в parcelMap
// убедитесь, что значения полей полученных посылок заполнены верно
par, ok := parcelMap[parcel.Number]
require.True(t, ok)
require.Equal(t, par.Address, parcel.Address)
require.Equal(t, par.Client, parcel.Client)
require.Equal(t, par.CreatedAt, parcel.CreatedAt)
require.Equal(t, par.Status, parcel.Status)
}
}
Binary file modified tracker.db
Binary file not shown.