diff --git a/src/myaktion/handler/campaign.go b/src/myaktion/handler/campaign.go index 3ca57ede6201dd7772ddcc25b68fc7b21b047af3..cfacb25aafd357ed698c1f83955654c215ce3be4 100644 --- a/src/myaktion/handler/campaign.go +++ b/src/myaktion/handler/campaign.go @@ -36,6 +36,79 @@ func GetCampaigns(w http.ResponseWriter, r *http.Request) { sendJson(w, campaigns) } +func GetCampaign(w http.ResponseWriter, r *http.Request) { + id, err := getId(r) + if err != nil { + log.Errorf("Failed to extract ID from request: %v", err) + http.Error(w, "Invalid campaign ID", http.StatusBadRequest) + return + } + campaign, err := service.GetCampaignByID(id) + if err != nil { + log.Errorf("Error retrieving campaign with ID %d: %v", id, err) + http.Error(w, "Campaign not found", http.StatusNotFound) + return + } + sendJson(w, campaign) +} + +func UpdateCampaign(w http.ResponseWriter, r *http.Request) { + var campaign *model.Campaign + campaign, err := getCampaign(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + id, err := getId(r) + if err != nil { + log.Errorf("Failed to extract ID from request: %v", err) + http.Error(w, "Invalid campaign ID", http.StatusBadRequest) + return + } + campaign.ID = id + if err := service.UpdateCampaign(campaign); err != nil { + log.Errorf("Error updating campaign with ID %d: %v", id, err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + sendJson(w, campaign) +} + +func DeleteCampaign(w http.ResponseWriter, r *http.Request) { + id, err := getId(r) + if err != nil { + log.Errorf("Failed to extract ID from request: %v", err) + http.Error(w, "Invalid campaign ID", http.StatusBadRequest) + return + } + if err := service.DeleteCampaign(id); err != nil { + log.Errorf("Error deleting campaign with ID %d: %v", id, err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + sendJson(w, result{Success: "Campaign deleted successfully"}) +} + +func AddDonation(w http.ResponseWriter, r *http.Request) { + id, err := getId(r) + if err != nil { + log.Errorf("Failed to extract ID from request: %v", err) + http.Error(w, "Invalid campaign ID", http.StatusBadRequest) + return + } + donation, err := getDonation(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := service.AddDonation(id, donation); err != nil { + log.Errorf("Error adding donation to campaign with ID %d: %v", id, err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + sendJson(w, donation) +} + func getCampaign(r *http.Request) (*model.Campaign, error) { var campaign model.Campaign err := json.NewDecoder(r.Body).Decode(&campaign) @@ -45,3 +118,13 @@ func getCampaign(r *http.Request) (*model.Campaign, error) { } return &campaign, nil } + +func getDonation(r *http.Request) (*model.Donation, error) { + var donation model.Donation + err := json.NewDecoder(r.Body).Decode(&donation) + if err != nil { + log.Errorf("Can't serialize request body to donation struct: %v", err) + return nil, err + } + return &donation, nil +} diff --git a/src/myaktion/main.go b/src/myaktion/main.go index 6f7c8729c8c70f406b09d0e3263d5ae5ef1c4461..fd0f6512a83f9d27afdc1f58cace3567f40f32c0 100644 --- a/src/myaktion/main.go +++ b/src/myaktion/main.go @@ -30,6 +30,10 @@ func main() { router.HandleFunc("/health", handler.Health).Methods("GET") router.HandleFunc("/campaigns", handler.CreateCampaign).Methods("POST") router.HandleFunc("/campaigns", handler.GetCampaigns).Methods("GET") + router.HandleFunc("/campaigns/{id}", handler.GetCampaign).Methods("GET") + router.HandleFunc("/campaigns/{id}", handler.UpdateCampaign).Methods("PUT") + router.HandleFunc("/campaigns/{id}", handler.DeleteCampaign).Methods("DELETE") + router.HandleFunc("/campaigns/{id}/donations", handler.AddDonation).Methods("POST") if err := http.ListenAndServe(":8000", router); err != nil { log.Fatal(err) } diff --git a/src/myaktion/model/campaign.go b/src/myaktion/model/campaign.go index 0451a19803b2109250372746d18f92758e4e25ee..47c8cd42fe5da7b724635ac643e28185e95933e3 100644 --- a/src/myaktion/model/campaign.go +++ b/src/myaktion/model/campaign.go @@ -9,6 +9,6 @@ type Campaign struct { TargetAmount float64 `gorm:"notNull;check:target_amount >= 10.0"` DonationMinimum float64 `gorm:"notNull;check:donation_minimum >= 1.0"` AmountDonatedSoFar float64 `gorm:"-"` - Donation []Donation `gorm:"foreignKey:CampaignID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` + Donations []Donation `gorm:"foreignKey:CampaignID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` Account Account `gorm:"embedded;embeddedPrefix:account_"` } diff --git a/src/myaktion/scripts/start-mariadb.sh b/src/myaktion/scripts/start-mariadb.sh index 2cd94cb5654af05956fbe4b8a9185349ee1ba765..d85a08b2ccb04cb3badb1ee9eedf7b47e895d9c6 100644 --- a/src/myaktion/scripts/start-mariadb.sh +++ b/src/myaktion/scripts/start-mariadb.sh @@ -1,2 +1,7 @@ #!/usr/bin/env bash - docker run -d -p 3306:3306 --name database -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=myaktion mariadb:10.5 \ No newline at end of file + docker run -d -p 3306:3306 --name database -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=myaktion mariadb:10.5 + +# docker exec -it database /bin/bash (or use Docker Desktop) +# mysql -u root -p (then enter 'root') +# USE myaktion; +# SHOW TABLES; DESCRIBE <table_name>; SELECT * FROM <table_name>; ... \ No newline at end of file diff --git a/src/myaktion/service/campaign.go b/src/myaktion/service/campaign.go index 68ceaebacc3fa78e377d1bc679ca7385a1a38121..7e73ec4fdf4d2b14de3e0a0473f14f3b3df4e85b 100644 --- a/src/myaktion/service/campaign.go +++ b/src/myaktion/service/campaign.go @@ -26,3 +26,43 @@ func GetCampaigns() ([]model.Campaign, error) { log.Tracef("Retrived: %v", campaigns) return campaigns, nil } + +func GetCampaignByID(id uint) (*model.Campaign, error) { + var campaign model.Campaign + result := db.DB.Preload("Donations").First(&campaign, id) + if result.Error != nil { + return nil, result.Error + } + log.Tracef("Retrived: %v", campaign) + return &campaign, nil +} + +func UpdateCampaign(campaign *model.Campaign) error { + result := db.DB.Save(campaign) + if result.Error != nil { + return result.Error + } + log.Infof("Successfully updated campaign with ID %v in database.", campaign.ID) + log.Tracef("Updated: %v", campaign) + return nil +} + +func DeleteCampaign(id uint) error { + result := db.DB.Delete(&model.Campaign{}, id) + if result.Error != nil { + return result.Error + } + log.Infof("Successfully deleted campaign with ID %v from database.", id) + return nil +} + +func AddDonation(campaignID uint, donation *model.Donation) error { + donation.CampaignID = campaignID + result := db.DB.Create(donation) + if result.Error != nil { + return result.Error + } + log.Infof("Successfully stored new donation with ID %v in database.", donation.ID) + log.Tracef("Stored: %v", donation) + return nil +}