From c1ba48cd6226676f3740f3d6fa3d10364302139a Mon Sep 17 00:00:00 2001 From: ras0q Date: Sat, 24 Jun 2023 21:54:16 +0900 Subject: [PATCH] Revert "Merge pull request #376 from traPtitech/feat/unique-event-on-same-time" This reverts commit 01e2de3e09dc86db2c5cd3989734e5c314a9f76d, reversing changes made to 80f4a6e7c7451e750250d68fda082a6f5fe3ea3b. --- infra/db/db_test.go | 4 +- infra/db/event_test.go | 58 ++++++++++------------ infra/db/hooks.go | 23 +++------ infra/db/model.go | 12 ++--- infra/db/room_test.go | 77 ++++++++++++----------------- migration/current.go | 2 - migration/v13.go | 109 ----------------------------------------- migration/v14.go | 109 ----------------------------------------- 8 files changed, 72 insertions(+), 322 deletions(-) delete mode 100644 migration/v13.go delete mode 100644 migration/v14.go diff --git a/infra/db/db_test.go b/infra/db/db_test.go index f696e5ba..846e1944 100644 --- a/infra/db/db_test.go +++ b/infra/db/db_test.go @@ -138,7 +138,7 @@ func setupRepoWithUserGroup(t *testing.T, repo string) (*GormRepository, *assert func setupRepoWithUserRoom(t *testing.T, repo string) (*GormRepository, *assert.Assertions, *require.Assertions, *User, *Room) { t.Helper() r, assert, require := setupRepo(t, repo) - room, user := mustMakeRoom(t, r, "here_"+random.AlphaNumeric(10, false)) + room, user := mustMakeRoom(t, r, "here") return r, assert, require, user, room } @@ -146,7 +146,7 @@ func setupRepoWithUserGroupRoomEvent(t *testing.T, repo string) (*GormRepository t.Helper() r, assert, require := setupRepo(t, repo) - event, group, room, user := mustMakeEvent(t, r, "event-"+random.AlphaNumeric(10, false)) + event, group, room, user := mustMakeEvent(t, r, "event") return r, assert, require, user, group, room, event } diff --git a/infra/db/event_test.go b/infra/db/event_test.go index 8f08c33e..f059626b 100644 --- a/infra/db/event_test.go +++ b/infra/db/event_test.go @@ -6,6 +6,7 @@ import ( "github.com/go-sql-driver/mysql" "github.com/gofrs/uuid" + "github.com/jinzhu/copier" "github.com/traPtitech/knoQ/domain" "github.com/traPtitech/knoQ/utils/random" "gorm.io/gorm" @@ -14,26 +15,24 @@ import ( func Test_createEvent(t *testing.T) { r, assert, require, user, room := setupRepoWithUserRoom(t, common) - newParams := func() WriteEventParams { - return WriteEventParams{ - CreatedBy: user.ID, - WriteEventParams: domain.WriteEventParams{ - Name: "event-" + random.AlphaNumeric(10, false), - GroupID: mustNewUUIDV4(t), - RoomID: room.ID, - TimeStart: time.Now(), - TimeEnd: time.Now().Add(1 * time.Minute), - AllowTogether: true, - Admins: []uuid.UUID{user.ID}, - Tags: []domain.EventTagParams{ - {Name: "go", Locked: true}, {Name: "golang"}, - }, + params := WriteEventParams{ + CreatedBy: user.ID, + WriteEventParams: domain.WriteEventParams{ + Name: "first event", + GroupID: mustNewUUIDV4(t), + RoomID: room.ID, + TimeStart: time.Now(), + TimeEnd: time.Now().Add(1 * time.Minute), + AllowTogether: true, + Admins: []uuid.UUID{user.ID}, + Tags: []domain.EventTagParams{ + {Name: "go", Locked: true}, {Name: "golang"}, }, - } + }, } t.Run("create event", func(t *testing.T) { - event, err := createEvent(r.db, newParams()) + event, err := createEvent(r.db, params) require.NoError(err) assert.NotNil(event.ID) @@ -47,28 +46,36 @@ func Test_createEvent(t *testing.T) { _, err := createOrGetTag(r.db, "Go") require.NoError(err) - p := newParams() + var p WriteEventParams + require.NoError(copier.Copy(&p, ¶ms)) + p.Tags = append(p.Tags, domain.EventTagParams{Name: "Go"}) _, err = createEvent(r.db, p) require.NoError(err) }) t.Run("wrong time", func(t *testing.T) { - p := newParams() + var p WriteEventParams + require.NoError(copier.Copy(&p, ¶ms)) + p.TimeStart = time.Now().Add(10 * time.Minute) _, err := createEvent(r.db, p) assert.ErrorIs(err, ErrTimeConsistency) }) t.Run("wrong room time", func(t *testing.T) { - p := newParams() + var p WriteEventParams + require.NoError(copier.Copy(&p, ¶ms)) + p.AllowTogether = false _, err := createEvent(r.db, p) assert.ErrorIs(err, ErrTimeConsistency) }) t.Run("create event with place", func(t *testing.T) { - p := newParams() + var p WriteEventParams + require.NoError(copier.Copy(&p, ¶ms)) + p.RoomID = uuid.Nil p.Place = "instant room" event, err := createEvent(r.db.Debug(), p) @@ -79,17 +86,6 @@ func Test_createEvent(t *testing.T) { assert.NotEqual(uuid.Nil, e.RoomID) assert.Equal(p.Place, e.Room.Place) }) - - t.Run("cannot create event with same name, time", func(t *testing.T) { - p := newParams() - _, err := createEvent(r.db, p) - require.NoError(err) - - _, err = createEvent(r.db, p) - var me *mysql.MySQLError - require.ErrorAs(err, &me) - assert.Equal(uint16(1062), me.Number) - }) } func Test_updateEvent(t *testing.T) { diff --git a/infra/db/hooks.go b/infra/db/hooks.go index 38ad3662..078c57fb 100644 --- a/infra/db/hooks.go +++ b/infra/db/hooks.go @@ -17,24 +17,15 @@ func (e *Event) BeforeSave(tx *gorm.DB) (err error) { } if e.RoomID == uuid.Nil { - if e.Room.Place == "" { + if e.Room.Place != "" { + e.Room.Verified = false + e.Room.TimeStart = e.TimeStart + e.Room.TimeEnd = e.TimeEnd + e.Room.CreatedByRefer = e.CreatedByRefer + e.Room.Admins = ConvSEventAdminToSRoomAdmin(e.Admins) + } else { return NewValueError(ErrRoomUndefined, "roomID", "place") } - - if err := tx. - Where(&Room{Place: e.Room.Place, TimeStart: e.TimeStart, TimeEnd: e.TimeEnd}). - First(&e.Room). - Error; err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - e.Room.Verified = false - e.Room.TimeStart = e.TimeStart - e.Room.TimeEnd = e.TimeEnd - e.Room.CreatedByRefer = e.CreatedByRefer - e.Room.Admins = ConvSEventAdminToSRoomAdmin(e.Admins) - } else { - return err - } - } } // 時間整合性 diff --git a/infra/db/model.go b/infra/db/model.go index 5f53b9f5..31cc7c33 100644 --- a/infra/db/model.go +++ b/infra/db/model.go @@ -92,10 +92,10 @@ type RoomAdmin struct { //go:generate go run github.com/fuji8/gotypeconverter/cmd/gotypeconverter@latest -s []*Room -d []*domain.Room -o converter.go . type Room struct { ID uuid.UUID `gorm:"type:char(36);primaryKey"` - Place string `gorm:"type:varchar(32); uniqueIndex:idx_place_time_start_time_end"` + Place string `gorm:"type:varchar(32);"` Verified bool - TimeStart time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_place_time_start_time_end"` - TimeEnd time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_place_time_start_time_end"` + TimeStart time.Time `gorm:"type:DATETIME; index"` + TimeEnd time.Time `gorm:"type:DATETIME; index"` Events []Event `gorm:"->; constraint:-"` // readOnly Admins []RoomAdmin CreatedByRefer uuid.UUID `gorm:"type:char(36);" cvt:"CreatedBy, <-"` @@ -173,14 +173,14 @@ type EventAttendee struct { //go:generate go run github.com/fuji8/gotypeconverter/cmd/gotypeconverter@latest -s []*Event -d []*domain.Event -o converter.go . type Event struct { ID uuid.UUID `gorm:"type:char(36); primaryKey"` - Name string `gorm:"type:varchar(32); not null; uniqueIndex:idx_name_time_start_time_end"` + Name string `gorm:"type:varchar(32); not null"` Description string `gorm:"type:TEXT"` GroupID uuid.UUID `gorm:"type:char(36); not null; index"` Group Group `gorm:"->; foreignKey:GroupID; constraint:-"` RoomID uuid.UUID `gorm:"type:char(36); not null; index"` Room Room `gorm:"foreignKey:RoomID; constraint:OnDelete:CASCADE;" cvt:"write:Place"` - TimeStart time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_name_time_start_time_end"` - TimeEnd time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_name_time_start_time_end"` + TimeStart time.Time `gorm:"type:DATETIME; index"` + TimeEnd time.Time `gorm:"type:DATETIME; index"` CreatedByRefer uuid.UUID `gorm:"type:char(36); not null" cvt:"CreatedBy, <-"` CreatedBy User `gorm:"->; foreignKey:CreatedByRefer; constraint:OnDelete:CASCADE;" cvt:"->"` Admins []EventAdmin diff --git a/infra/db/room_test.go b/infra/db/room_test.go index 2ed05133..29c6fd5d 100644 --- a/infra/db/room_test.go +++ b/infra/db/room_test.go @@ -6,88 +6,71 @@ import ( "github.com/go-sql-driver/mysql" "github.com/gofrs/uuid" + "github.com/jinzhu/copier" "github.com/traPtitech/knoQ/domain" - "github.com/traPtitech/knoQ/utils/random" ) func Test_createRoom(t *testing.T) { r, assert, require, user := setupRepoWithUser(t, common) - newParams := func() CreateRoomParams { - return CreateRoomParams{ - CreatedBy: user.ID, - Verified: false, - WriteRoomParams: domain.WriteRoomParams{ - Place: "create room_" + random.AlphaNumeric(10, false), - TimeStart: time.Now(), - TimeEnd: time.Now().Add(1 * time.Minute), - Admins: []uuid.UUID{user.ID}, - }, - } + params := CreateRoomParams{ + CreatedBy: user.ID, + Verified: false, + WriteRoomParams: domain.WriteRoomParams{ + Place: "create room", + TimeStart: time.Now(), + TimeEnd: time.Now().Add(1 * time.Minute), + Admins: []uuid.UUID{user.ID}, + }, } t.Run("create room", func(t *testing.T) { - room, err := createRoom(r.db, newParams()) + room, err := createRoom(r.db, params) require.NoError(err) assert.NotNil(room.ID) }) t.Run("wrong time", func(t *testing.T) { - p := newParams() - p.TimeStart, p.TimeEnd = p.TimeEnd, p.TimeStart - _, err := createRoom(r.db, p) - assert.ErrorIs(err, ErrTimeConsistency) - }) + var p CreateRoomParams + require.NoError(copier.Copy(&p, ¶ms)) - t.Run("cannot create room with same place, time", func(t *testing.T) { - p := newParams() + p.TimeStart = time.Now().Add(10 * time.Minute) _, err := createRoom(r.db, p) - require.NoError(err) - - _, err = createRoom(r.db, p) - var me *mysql.MySQLError - require.ErrorAs(err, &me) - assert.Equal(uint16(1062), me.Number) + assert.ErrorIs(err, ErrTimeConsistency) }) } func Test_updateRoom(t *testing.T) { r, assert, require, user, room := setupRepoWithUserRoom(t, common) - newParams := func() UpdateRoomParams { - return UpdateRoomParams{ - CreatedBy: user.ID, - WriteRoomParams: domain.WriteRoomParams{ - Place: "update room_" + random.AlphaNumeric(10, false), - TimeStart: time.Now(), - TimeEnd: time.Now().Add(1 * time.Minute), - Admins: []uuid.UUID{user.ID}, - }, - } + params := UpdateRoomParams{ + CreatedBy: user.ID, + WriteRoomParams: domain.WriteRoomParams{ + Place: "update room", + TimeStart: time.Now(), + TimeEnd: time.Now().Add(1 * time.Minute), + Admins: []uuid.UUID{user.ID}, + }, } t.Run("update room", func(t *testing.T) { - p := newParams() - _, err := updateRoom(r.db, room.ID, p) + _, err := updateRoom(r.db, room.ID, params) require.NoError(err) ro, err := getRoom(roomFullPreload(r.db), room.ID) require.NoError(err) - assert.Equal(p.Place, ro.Place) + assert.Equal(params.Place, ro.Place) }) t.Run("update room with verified", func(t *testing.T) { - _p := newParams() - p := CreateRoomParams{ - WriteRoomParams: _p.WriteRoomParams, - Verified: true, - CreatedBy: _p.CreatedBy, - } + var p CreateRoomParams + require.NoError(copier.Copy(&p, ¶ms)) + p.Verified = true ro, err := createRoom(r.db, p) require.NoError(err) - _, err = updateRoom(r.db, ro.ID, newParams()) + _, err = updateRoom(r.db, ro.ID, params) require.NoError(err) roo, err := getRoom(r.db, ro.ID) @@ -96,7 +79,7 @@ func Test_updateRoom(t *testing.T) { }) t.Run("update random roomID", func(t *testing.T) { - _, err := updateRoom(r.db, mustNewUUIDV4(t), newParams()) + _, err := updateRoom(r.db, mustNewUUIDV4(t), params) var me *mysql.MySQLError require.ErrorAs(err, &me) assert.Equal(uint16(1452), me.Number) diff --git a/migration/current.go b/migration/current.go index e9488bc5..b4790920 100644 --- a/migration/current.go +++ b/migration/current.go @@ -19,7 +19,5 @@ func Migrations() []*gormigrate.Migration { v10(), v11(), v12(), - v13(), - v14(), } } diff --git a/migration/v13.go b/migration/v13.go deleted file mode 100644 index 325e0d88..00000000 --- a/migration/v13.go +++ /dev/null @@ -1,109 +0,0 @@ -package migration - -import ( - "fmt" - "time" - - gormigrate "github.com/go-gormigrate/gormigrate/v2" - "github.com/gofrs/uuid" - "gorm.io/gorm" -) - -// eventsにname,time_start,time_endの複合ユニークインデックスを追加 - -type v13Event struct { - ID uuid.UUID `gorm:"type:char(36); primaryKey"` - Name string `gorm:"type:varchar(32); not null; uniqueIndex:idx_name_time_start_time_end"` - TimeStart time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_name_time_start_time_end"` - TimeEnd time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_name_time_start_time_end"` -} - -func (*v13Event) TableName() string { - return "events" -} - -type v13UpdateEvent struct { - ID1 uuid.UUID - Name1 string - ID2 uuid.UUID - Name2 string - TimeStart time.Time - TimeEnd time.Time -} - -func v13() *gormigrate.Migration { - return &gormigrate.Migration{ - ID: "13", - Migrate: func(tx *gorm.DB) error { - query := ` -SELECT - e1.id AS id1, - e1.name AS name1, - e2.id AS id2, - e2.name AS name2, - e1.time_start, - e1.time_end -FROM - events e1 -INNER JOIN events e2 - ON e1.id < e2.id - AND e1.name = e2.name - AND e1.time_start = e2.time_start - AND e1.time_end = e2.time_end -ORDER BY - e1.id ASC, - e2.id ASC -` - - if err := tx.Transaction(func(tx *gorm.DB) error { - duplicatedEvents := []v13UpdateEvent{} - if err := tx.Raw(query).Scan(&duplicatedEvents).Error; err != nil { - return err - } - - for _, e := range duplicatedEvents { - i := 1 - for { - var count int64 - if err := tx. - Table("events"). - Where( - "name = ? AND time_start = ? AND time_end = ?", - fmt.Sprintf("%s (%d)", e.Name2, i), - e.TimeStart, - e.TimeEnd, - ). - Count(&count). - Error; err != nil { - return err - } - - if count == 0 { - break - } - - i++ - } - - if err := tx. - Table("events"). - Where("id = ?", e.ID2). - Update("name", fmt.Sprintf("%s (%d)", e.Name2, i)). - Error; err != nil { - return err - } - } - - if err := tx.AutoMigrate(&v13Event{}); err != nil { - return err - } - - return nil - }); err != nil { - return err - } - - return nil - }, - } -} diff --git a/migration/v14.go b/migration/v14.go deleted file mode 100644 index dcf34c01..00000000 --- a/migration/v14.go +++ /dev/null @@ -1,109 +0,0 @@ -package migration - -import ( - "fmt" - "time" - - gormigrate "github.com/go-gormigrate/gormigrate/v2" - "github.com/gofrs/uuid" - "gorm.io/gorm" -) - -// roomsにplace,time_start,time_endの複合ユニークインデックスを追加 - -type v14Room struct { - ID uuid.UUID `gorm:"type:char(36);primaryKey"` - Place string `gorm:"type:varchar(32); uniqueIndex:idx_place_time_start_time_end"` - TimeStart time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_place_time_start_time_end"` - TimeEnd time.Time `gorm:"type:DATETIME; index; uniqueIndex:idx_place_time_start_time_end"` -} - -type v14UpdateRoom struct { - ID1 uuid.UUID - Place1 string - ID2 uuid.UUID - Place2 string - TimeStart time.Time - TimeEnd time.Time -} - -func (*v14Room) TableName() string { - return "rooms" -} - -func v14() *gormigrate.Migration { - return &gormigrate.Migration{ - ID: "14", - Migrate: func(tx *gorm.DB) error { - query := ` -SELECT - r1.id AS id1, - r1.place AS place1, - r2.id AS id2, - r2.place AS place2, - r1.time_start, - r1.time_end -FROM - rooms r1 -INNER JOIN rooms r2 - ON r1.id < r2.id - AND r1.place = r2.place - AND r1.time_start = r2.time_start - AND r1.time_end = r2.time_end -ORDER BY - r1.id ASC, - r2.id ASC -` - - if err := tx.Transaction(func(tx *gorm.DB) error { - duplicatedRooms := []v14UpdateRoom{} - if err := tx.Raw(query).Scan(&duplicatedRooms).Error; err != nil { - return err - } - - for _, r := range duplicatedRooms { - i := 1 - for { - var count int64 - if err := tx. - Table("rooms"). - Where( - "place = ? AND time_start = ? AND time_end = ?", - fmt.Sprintf("%s (%d)", r.Place2, i), - r.TimeStart, - r.TimeEnd, - ). - Count(&count). - Error; err != nil { - return err - } - - if count == 0 { - break - } - - i++ - } - - if err := tx. - Table("rooms"). - Where("id = ?", r.ID2). - Update("place", fmt.Sprintf("%s (%d)", r.Place2, i)). - Error; err != nil { - return err - } - } - - if err := tx.AutoMigrate(&v14Room{}); err != nil { - return err - } - - return nil - }); err != nil { - return err - } - - return nil - }, - } -}