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

Unique dish.{name, cafeteriaID} #325

Merged
merged 12 commits into from
Mar 13, 2024
11 changes: 5 additions & 6 deletions server/backend/cafeteria.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,11 @@ func (s *CampusServer) CreateDishRating(ctx context.Context, input *pb.CreateDis
resPath := imageWrapper(input.Image, "dishes", dishInMensa.Dish)

rating := model.DishRating{
Comment: input.Comment,
CafeteriaID: cafeteriaID,
DishID: dishInMensa.Dish,
Points: input.Points,
Timestamp: time.Now(),
Image: resPath,
Comment: input.Comment,
DishID: dishInMensa.Dish,
Points: input.Points,
Timestamp: time.Now(),
Image: resPath,
}
if err := tx.Create(&rating).Error; err != nil {
log.WithError(err).Error("while creating a new dishInMensa rating.")
Expand Down
28 changes: 15 additions & 13 deletions server/backend/cron/dish_name_download.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cron

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
Expand Down Expand Up @@ -95,25 +96,26 @@ func downloadDailyDishes(c *CronService) {
CafeteriaID: v.Cafeteria,
}

var count int64
var dishId int64
if err := c.db.Model(&model.Dish{}).
Where("name = ? AND cafeteriaID = ?", dish.Name, dish.CafeteriaID).
Select("dish").
First(&dishId).
Count(&count).Error; err != nil {
log.WithError(err).Error("Error while checking whether this is already in database")
}
if count == 0 {
var dbDish model.Dish
if err := c.db.First(&dbDish, "name = ? AND cafeteriaID = ?", dish.Name, dish.CafeteriaID).Error; err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
if err := c.db.Create(&dish).Error; err != nil {
log.WithError(err).Error("Error while creating new CanteenDish entry with name {}. CanteenDish won't be saved", dish.Name)
log.WithError(err).WithField("name", dish.Name).Error("Error while creating new CanteenDish entry. CanteenDish won't be saved")
}
addDishTagsToMapping(dish.Dish, dish.Name, c.db)
dishId = dish.Dish
dbDish = dish
} else if err != nil {
log.WithError(err).Error("Error while checking whether the dish is already in database")
}

if dbDish.Type != dish.Type {
if err := c.db.Where("dish = ?", dbDish.Dish).Updates(&dish).Error; err != nil {
log.WithError(err).WithField("from", dish.Type).WithField("to", dish.Type).Error("Error while updating dish to new type")
}
}

if weekliesWereAdded == 0 {
errCreate := c.db.Create(&model.DishesOfTheWeek{
DishID: dishId,
DishID: dbDish.Dish,
Year: int32(year),
Week: int32(week),
Day: int32(weekDayIndex),
Expand Down
45 changes: 45 additions & 0 deletions server/backend/migration/20240311000000.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package migration

import (
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)

// migrate20240311000000
// made sure that dishes have the correct indexes
// changed how `dish_rating` is bound to `dish`
func migrate20240311000000() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "20240311000000",
Migrate: func(tx *gorm.DB) error {
// make sure that dish_rating is FK-bound to dish
if err := tx.Exec("alter table dish_rating modify dishID int").Error; err != nil {
return err
}
if err := tx.Exec("alter table dish_rating add constraint dish_rating_dish_dish_fk foreign key (dishID) references dish (dish) on update cascade on delete cascade").Error; err != nil {
return err
}
// because dishes already have a cafeteria, storing this again is not necessary
if err := tx.Exec("alter table dish_rating drop column cafeteriaID").Error; err != nil {
return err
}
// uniqueness
return tx.Exec("create unique index dish_name_cafeteriaID_uindex on dish (name, cafeteriaID)").Error
},
Rollback: func(tx *gorm.DB) error {
// make sure that dish_rating is FK-bound to dishes
if err := tx.Exec("alter table dish_rating drop constraint dish_rating_dish_dish_fk").Error; err != nil {
return err
}
if err := tx.Exec("alter table dish_rating modify dishID int not null").Error; err != nil {
return err
}
// because dishes already have a cafeteria, storing this agiain is not nessesary
if err := tx.Exec("alter table dish_rating add column cafeteriaID int not null").Error; err != nil {
return err
}
// uniqueness
return tx.Exec("drop index dish_name_cafeteriaID_uindex on dish").Error
},
}
}
6 changes: 3 additions & 3 deletions server/backend/migration/20240312000000.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"gorm.io/gorm"
)

// migrate20240212000000
// migrate20240312000000
// implemented a basic variant of spam protection
func migrate20240212000000() *gormigrate.Migration {
func migrate20240312000000() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "20240212000000",
ID: "20240312000000",
Migrate: func(tx *gorm.DB) error {
if err := tx.Exec("alter table feedback modify email_id text charset utf8mb3 not null").Error; err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion server/backend/migration/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ func manualMigrate(db *gorm.DB) error {
migrate20240102000000(),
migrate20240103000000(),
migrate20240207000000(),
migrate20240212000000(),
migrate20240311000000(),
migrate20240312000000(),
}
return gormigrate.New(db, gormigrateOptions, migrations).Migrate()
}
Expand Down
4 changes: 2 additions & 2 deletions server/model/dish.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ var (
// Dish represents one dish fin a specific cafeteria
type Dish struct {
Dish int64 `gorm:"primary_key;AUTO_INCREMENT;column:dish;type:int;not null;" json:"dish"`
Name string `gorm:"column:name;type:text;not null;" json:"name" `
Name string `gorm:"column:name;type:text;not null;uniqueIndex:dish_name_cafeteriaID_uindex" json:"name" `
Type string `gorm:"column:type;type:text;not null;" json:"type" `
CafeteriaID int64 `gorm:"column:cafeteriaID;foreignKey:cafeteria;type:int;not null;" json:"cafeteriaID"`
CafeteriaID int64 `gorm:"column:cafeteriaID;foreignKey:cafeteria;type:int;not null;uniqueIndex:dish_name_cafeteriaID_uindex" json:"cafeteriaID"`
}

// TableName sets the insert table name for this struct type
Expand Down
14 changes: 7 additions & 7 deletions server/model/dish_rating.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
)

type DishRating struct {
DishRating int64 `gorm:"primary_key;AUTO_INCREMENT;column:dishRating;type:int;not null;" json:"dishRating"`
Points int32 `gorm:"column:points;type:int;not null;" json:"points"`
CafeteriaID int64 `gorm:"column:cafeteriaID;foreignKey:cafeteria;type:int;not null;" json:"cafeteriaID"`
DishID int64 `gorm:"column:dishID;foreignKey:dish;type:int;not null;" json:"dishID"`
Comment string `gorm:"column:comment;type:text;" json:"comment"`
Timestamp time.Time `gorm:"column:timestamp;type:timestamp;not null;" json:"timestamp"`
Image string `gorm:"column:image;type:text;" json:"image"`
DishRating int64 `gorm:"primary_key;AUTO_INCREMENT;column:dishRating;type:int;not null;" json:"dishRating"`
Points int32 `gorm:"column:points;type:int;not null;" json:"points"`
DishID int64 `gorm:"column:dishID;type:int;not null;" json:"dishID"`
Dish Dish `gorm:"foreignKey:dishID;references:dish;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
Comment string `gorm:"column:comment;type:text;" json:"comment"`
Timestamp time.Time `gorm:"column:timestamp;type:timestamp;not null;" json:"timestamp"`
Image string `gorm:"column:image;type:text;" json:"image"`
}

// TableName sets the insert table name for this struct type
Expand Down
Loading