From c8b89e06e0832952709f49145984a6bde6a70692 Mon Sep 17 00:00:00 2001 From: Islam Boziev Date: Fri, 30 May 2025 07:34:22 +0300 Subject: [PATCH] second --- main.go | 8 ++++- parcel.go | 49 +++++++++++++++++++++++++---- parcel_test.go | 85 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 123 insertions(+), 19 deletions(-) diff --git a/main.go b/main.go index 44c32b3f..8153cd32 100644 --- a/main.go +++ b/main.go @@ -98,8 +98,14 @@ func (s ParcelService) Delete(number int) error { func main() { // настройте подключение к БД + db, err := sql.Open("sqlite", "tracker.db") + if err != nil { + fmt.Println(err) + return + } + defer db.Close() - store := // создайте объект ParcelStore функцией NewParcelStore + store := NewParcelStore(db) // создайте объект ParcelStore функцией NewParcelStore service := NewParcelService(store) // регистрация посылки diff --git a/parcel.go b/parcel.go index db6c815d..08ea26dd 100644 --- a/parcel.go +++ b/parcel.go @@ -14,9 +14,20 @@ func NewParcelStore(db *sql.DB) ParcelStore { func (s ParcelStore) Add(p Parcel) (int, error) { // реализуйте добавление строки в таблицу parcel, используйте данные из переменной p - + res, err := s.db.Exec("INSERT INTO parcel (client, status, address, created_at) VALUES (:client, :status, :address, :created_at)", + sql.Named("client", p.Client), + sql.Named("status", p.Status), + sql.Named("address", p.Address), + sql.Named("created_at", p.CreatedAt)) + if err != nil { + return 0, err + } // верните идентификатор последней добавленной записи - return 0, nil + id, err := res.LastInsertId() + if err != nil { + return 0, err + } + return int(id), nil } func (s ParcelStore) Get(number int) (Parcel, error) { @@ -26,22 +37,37 @@ func (s ParcelStore) Get(number int) (Parcel, error) { // заполните объект Parcel данными из таблицы p := Parcel{} + row := s.db.QueryRow("SELECT number, client, status, address, created_at FROM parcel WHERE number = :number", sql.Named("number", number)) + err := row.Scan(&p.Number, &p.Client, &p.Status, &p.Address, &p.CreatedAt) + if err != nil { + return p, err + } return p, nil } func (s ParcelStore) GetByClient(client int) ([]Parcel, error) { // реализуйте чтение строк из таблицы parcel по заданному client // здесь из таблицы может вернуться несколько строк - - // заполните срез Parcel данными из таблицы + p := Parcel{} var res []Parcel + row := s.db.QueryRow("SELECT number, client, status, address, created_at FROM parcel WHERE client = :client", sql.Named("client", client)) + err := row.Scan(&p.Number, &p.Client, &p.Status, &p.Address, &p.CreatedAt) + if err != nil { + return res, err + } + res = append(res, p) // заполните срез Parcel данными из таблицы return res, nil } func (s ParcelStore) SetStatus(number int, status string) error { // реализуйте обновление статуса в таблице parcel - + _, err := s.db.Exec("UPDATE parcel SET status = :status WHERE number = :number", + sql.Named("status", status), + sql.Named("number", number)) + if err != nil { + return err + } return nil } @@ -49,12 +75,23 @@ func (s ParcelStore) SetAddress(number int, address string) error { // реализуйте обновление адреса в таблице parcel // менять адрес можно только если значение статуса registered + _, err := s.db.Exec("UPDATE parcel SET address = :address WHERE number = :number AND status = :status", + sql.Named("address", address), + sql.Named("number", number), + sql.Named("status", "registered")) + if err != nil { + return err + } + return nil } func (s ParcelStore) Delete(number int) error { // реализуйте удаление строки из таблицы parcel // удалять строку можно только если значение статуса registered + _, err := s.db.Exec("DELETE FROM parcel WHERE number = :number AND status = :status", + sql.Named("number", number), + sql.Named("status", "registered")) - return nil + return err } diff --git a/parcel_test.go b/parcel_test.go index d1b93827..337bb8f1 100644 --- a/parcel_test.go +++ b/parcel_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -31,34 +32,65 @@ func getTestParcel() Parcel { // TestAddGetDelete проверяет добавление, получение и удаление посылки func TestAddGetDelete(t *testing.T) { // prepare - db, err := // настройте подключение к БД + db, err := sql.Open("sqlite", "tracker.db") + if err != nil { + require.NoError(t, err) + } + defer db.Close() // настройте подключение к БД store := NewParcelStore(db) parcel := getTestParcel() // add // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора + id, err := store.Add(parcel) + require.NoError(t, err) + require.NotEmpty(t, id) + parcel.Number = int(id) // get // получите только что добавленную посылку, убедитесь в отсутствии ошибки // проверьте, что значения всех полей в полученном объекте совпадают со значениями полей в переменной parcel - + got, err := store.Get(id) + require.NoError(t, err) + require.Equal(t, parcel, got) // delete // удалите добавленную посылку, убедитесь в отсутствии ошибки // проверьте, что посылку больше нельзя получить из БД + err = store.Delete(id) + require.NoError(t, err) + + got, err = store.Get(id) + require.Equal(t, sql.ErrNoRows, err) + require.Empty(t, got) } // TestSetAddress проверяет обновление адреса func TestSetAddress(t *testing.T) { // prepare - db, err := // настройте подключение к БД - + db, err := sql.Open("sqlite", "tracker.db") + if err != nil { + require.NoError(t, err) + } + defer db.Close() // настройте подключение к БД + store := NewParcelStore(db) + parcel := getTestParcel() // add // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора + id, err := store.Add(parcel) + require.NoError(t, err) + require.NotEmpty(t, id) + parcel.Number = int(id) // set address // обновите адрес, убедитесь в отсутствии ошибки newAddress := "new test address" + err = store.SetAddress(id, newAddress) + require.NoError(t, err) + + got, err := store.Get(id) + require.NoError(t, err) + require.Equal(t, newAddress, got.Address) // check // получите добавленную посылку и убедитесь, что адрес обновился } @@ -66,14 +98,29 @@ func TestSetAddress(t *testing.T) { // TestSetStatus проверяет обновление статуса func TestSetStatus(t *testing.T) { // prepare - db, err := // настройте подключение к БД + db, err := sql.Open("sqlite", "tracker.db") + if err != nil { + require.NoError(t, err) + } + defer db.Close() // настройте подключение к БД + store := NewParcelStore(db) + parcel := getTestParcel() // настройте подключение к БД // add // добавьте новую посылку в БД, убедитесь в отсутствии ошибки и наличии идентификатора + id, err := store.Add(parcel) + require.NoError(t, err) + require.NotEmpty(t, id) + parcel.Number = int(id) // set status // обновите статус, убедитесь в отсутствии ошибки + err = store.SetStatus(id, ParcelStatusSent) + require.NoError(t, err) + got, err := store.Get(id) + require.NoError(t, err) + require.Equal(t, ParcelStatusSent, got.Status) // check // получите добавленную посылку и убедитесь, что статус обновился } @@ -81,8 +128,13 @@ func TestSetStatus(t *testing.T) { // TestGetByClient проверяет получение посылок по идентификатору клиента func TestGetByClient(t *testing.T) { // prepare - db, err := // настройте подключение к БД + db, err := sql.Open("sqlite", "tracker.db") + if err != nil { + require.NoError(t, err) + } + defer db.Close() // настройте подключение к БД + store := NewParcelStore(db) parcels := []Parcel{ getTestParcel(), getTestParcel(), @@ -98,7 +150,11 @@ 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 @@ -108,14 +164,19 @@ func TestGetByClient(t *testing.T) { } // get by client - storedParcels, err := // получите список посылок по идентификатору клиента, сохранённого в переменной client - // убедитесь в отсутствии ошибки - // убедитесь, что количество полученных посылок совпадает с количеством добавленных + storedParcels, err := store.GetByClient(client) // получите список посылок по идентификатору клиента, сохранённого в переменной client + require.NoError(t, err) // убедитесь в отсутствии ошибки + require.Equal(t, len(parcels), len(parcelMap)) // убедитесь, что количество полученных посылок совпадает с количеством добавленных // check for _, parcel := range storedParcels { - // в parcelMap лежат добавленные посылки, ключ - идентификатор посылки, значение - сама посылка - // убедитесь, что все посылки из storedParcels есть в parcelMap + stored, exists := parcelMap[parcel.Number] // в parcelMap лежат добавленные посылки, ключ - идентификатор посылки, значение - сама посылка + assert.True(t, exists, parcel.Number) // убедитесь, что все посылки из storedParcels есть в parcelMap + assert.Equal(t, stored.Number, parcel.Number) + assert.Equal(t, stored.Client, parcel.Client) + assert.Equal(t, stored.Status, parcel.Status) + assert.Equal(t, stored.CreatedAt, parcel.CreatedAt) + assert.Equal(t, stored.Address, parcel.Address) // убедитесь, что значения полей полученных посылок заполнены верно } }