diff --git a/scripts/create_mariadb.sh b/scripts/create_mariadb.sh new file mode 100644 index 0000000000000000000000000000000000000000..c97b1ea66c59447917df62bf941656bdb764fa58 --- /dev/null +++ b/scripts/create_mariadb.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker run -d -p 3306:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=myaktion mariadb:10.5 \ No newline at end of file diff --git a/scripts/delete_mariadb.sh b/scripts/delete_mariadb.sh new file mode 100644 index 0000000000000000000000000000000000000000..6f30105108fad9ab90bd14fe11210d56410c2955 --- /dev/null +++ b/scripts/delete_mariadb.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker kill database && docker rm database \ No newline at end of file diff --git a/src/myaktion/db/db.go b/src/myaktion/db/db.go new file mode 100644 index 0000000000000000000000000000000000000000..33cada8c04cfb5da7706e1187e00cf7b57a9b598 --- /dev/null +++ b/src/myaktion/db/db.go @@ -0,0 +1,32 @@ +package db + +import ( + "fmt" + "os" + + log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/model" + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +var DB *gorm.DB + +func init() { + // init database + dsn := fmt.Sprintf("root:root@tcp(%s)/myaktion?charset=utf8&parseTime=True&loc=Local", os.Getenv("DB_CONNECT")) + log.Info("Using DSN for DB:", dsn) + var err error + DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) + if err != nil { + panic("failed to connect to database") + } + log.Info("Starting automatic migrations") + if err := DB.Debug().AutoMigrate(&model.Campaign{}); err != nil { + panic(err) + } + if err := DB.Debug().AutoMigrate(&model.Donation{}); err != nil { + panic(err) + } + log.Info("Automatic migrations finished") +} diff --git a/src/myaktion/go.mod b/src/myaktion/go.mod index 0c7df4320f2d34b20670ca39544cd5b3902e2a78..bce395fff6b9582aa41031076ab676898be87ea2 100644 --- a/src/myaktion/go.mod +++ b/src/myaktion/go.mod @@ -5,6 +5,13 @@ go 1.20 require ( github.com/gorilla/mux v1.8.0 github.com/sirupsen/logrus v1.9.0 + gorm.io/driver/mysql v1.5.0 + gorm.io/gorm v1.25.1 ) -require golang.org/x/sys v0.7.0 // indirect +require ( + github.com/go-sql-driver/mysql v1.7.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + golang.org/x/sys v0.7.0 // indirect +) diff --git a/src/myaktion/go.sum b/src/myaktion/go.sum index ee6c613ad34b39d2dfedbbacf0317974e70f00e9..0529ba52908c85c9ffe592095913c1191eec2e3f 100644 --- a/src/myaktion/go.sum +++ b/src/myaktion/go.sum @@ -1,8 +1,15 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 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/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= @@ -16,3 +23,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.0 h1:6hSAT5QcyIaty0jfnff0z0CLDjyRgZ8mlMHLqSt7uXM= +gorm.io/driver/mysql v1.5.0/go.mod h1:FFla/fJuCvyTi7rJQd27qlNX2v3L6deTR1GgTjSOLPo= +gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= diff --git a/src/myaktion/model/account.go b/src/myaktion/model/account.go index 8628334be9a6880bc3d3e8d6c3e793b41a6f70ea..a255ba6ab777f87f87b7f0baf90f2a5f14ad5174 100644 --- a/src/myaktion/model/account.go +++ b/src/myaktion/model/account.go @@ -1,7 +1,7 @@ package model type Account struct { - Name string `json:"name"` - BankName string `json:"bankName"` - Number string `json:"number"` + Name string `json:"name" gorm:"notNull"` + BankName string `json:"bankName" gorm:"notNull"` + Number string `json:"number" gorm:"notNull"` } diff --git a/src/myaktion/model/campaign.go b/src/myaktion/model/campaign.go index ae633b60e5adb63e5d730cf83a680f81aaa4f344..f6e65e4a63f0abb7b863f542b3adb2a93affa34e 100644 --- a/src/myaktion/model/campaign.go +++ b/src/myaktion/model/campaign.go @@ -1,12 +1,12 @@ package model type Campaign struct { - ID uint `json:"id"` - Name string `json:"name"` - OrganizerName string `json:"organizerName"` - TargetAmount float64 `json:"targetAmount"` - DonationMinimum float64 `json:"donationMinimum"` - AmountDonatedSoFar float64 `json:"amountDonatedSoFar"` - Account Account `json:"account"` - Donations []Donation `json:"donations"` + ID uint `json:"id" gorm:"primaryKey"` + Name string `json:"name" gorm:"notNull"` + OrganizerName string `json:"organizerName" gorm:"notNull"` + TargetAmount float64 `json:"targetAmount" gorm:"notNull; check:target_amount >= 10.0"` + DonationMinimum float64 `json:"donationMinimum" gorm:"notNull; check:donation_minimum >= 1.0"` + AmountDonatedSoFar float64 `json:"amountDonatedSoFar" gorm:"-"` + Account Account `json:"account" gorm:"embedded; embeddedPrefix:account_"` + Donations []Donation `json:"donations" gorm:"foreignKey: CampaignID; constraint:OnUpdate:CASCADE, OnDelete:CASCADE"` } diff --git a/src/myaktion/model/donation.go b/src/myaktion/model/donation.go index 972e21981c776041f99c089d2047947b2d6e2558..a07c0f46b24aa12b037f31b6376ea879450d0ee1 100644 --- a/src/myaktion/model/donation.go +++ b/src/myaktion/model/donation.go @@ -6,11 +6,12 @@ const ( ) type Donation struct { - Amount float64 `json:"amount"` - DonorName string `json:"donorName"` - ReceiptRequested bool `json:"receiptRequested"` - Account Account `json:"account"` - Status Status `json:"status"` + CampaignID uint `json:"campaignId"` + Amount float64 `json:"amount" gorm:"notNull"` + DonorName string `json:"donorName" gorm:"notNull"` + ReceiptRequested bool `json:"receiptRequested" gorm:"notNull"` + Account Account `json:"account" gorm:"embedded; embeddedPrefix:account_; foreignKey: CampaignID; constraint:OnUpdate:CASCADE, OnDelete:CASCADE"` + Status Status `json:"status" gorm:"notNull; type:ENUM('TRANSFERRED','IN_PROCESS')"` } type Status string diff --git a/src/myaktion/service/campaign.go b/src/myaktion/service/campaign.go index 510712b62121b59aac40f322150498cc65f2d9c0..d5971436e0f029acc4218bbc5dd73ac80cd75442 100644 --- a/src/myaktion/service/campaign.go +++ b/src/myaktion/service/campaign.go @@ -5,6 +5,7 @@ import ( log "github.com/sirupsen/logrus" + "gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/db" "gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/model" ) @@ -18,9 +19,11 @@ func init() { } func CreateCampaign(campaign *model.Campaign) error { - campaign.ID = actCampaignId - campaignStore[actCampaignId] = campaign - actCampaignId += 1 + result := db.DB.Create(campaign) + if result.Error != nil { + log.Info("Campaign creation failed.") + return result.Error + } log.Infof("Successfully stored new campaign with ID %v in database.", campaign.ID) log.Tracef("Stored: %v", campaign) @@ -40,8 +43,9 @@ func GetCampaign(id uint) (*model.Campaign, error) { func GetCampaigns() ([]model.Campaign, error) { var campaigns []model.Campaign - for _, campaign := range campaignStore { - campaigns = append(campaigns, *campaign) + result := db.DB.Preload("Donations").Find(&campaigns) + if result.Error != nil { + return nil, result.Error } log.Infof("Successfully retrieved %d campaigns.", len(campaigns)) log.Tracef("Retrieved: %v", campaigns)