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

🔥 Db refactoring #577

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
47 changes: 14 additions & 33 deletions infra/db/converter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions infra/db/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (e *Event) BeforeSave(tx *gorm.DB) (err error) {
e.Room.TimeStart = e.TimeStart
e.Room.TimeEnd = e.TimeEnd
e.Room.CreatedByRefer = e.CreatedByRefer
e.Room.Admins = ConvSEventAdminToSRoomAdmin(e.Admins)
e.Room.Admins = ConvSEventAdminToSUser(e.Admins)
} else {
return NewValueError(ErrRoomUndefined, "roomID", "place")
}
Expand Down Expand Up @@ -180,8 +180,7 @@ func (r *Room) BeforeSave(tx *gorm.DB) (err error) {
}

func (r *Room) BeforeUpdate(tx *gorm.DB) (err error) {
err = tx.Where("room_id", r.ID).Delete(&RoomAdmin{}).Error
if err != nil {
if err := tx.Model(&Room{ID: r.ID}).Association("Admins").Clear(); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Model(r) みたいなことをしていると rAdminsnil になってしまうみたい.(その仕様が書かれているドキュメントを見つけられてないが...)

return err
}
return nil
Expand Down
20 changes: 5 additions & 15 deletions infra/db/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ import (
var tables = []interface{}{
User{},
Token{},
Provider{},
Group{},
GroupMember{},
GroupAdmin{},
Tag{},
Room{},
RoomAdmin{},
Event{},
EventTag{}, // Eventより下にないと、overrideされる
EventAdmin{},
Expand Down Expand Up @@ -58,8 +56,7 @@ type Token struct {
}

type Provider struct {
UserID uuid.UUID `gorm:"type:char(36); primaryKey"`
Issuer string `gorm:"not null"`
Issuer string `gorm:"not null"`
Subject string
}

Expand All @@ -68,9 +65,9 @@ type User struct {
// アプリの管理者かどうか
Privilege bool `gorm:"not null"`
State int
IcalSecret string `gorm:"not null"`
Provider Provider `gorm:"foreignKey:UserID; constraint:OnDelete:CASCADE;"`
Token Token `gorm:"foreignKey:UserID; constraint:OnDelete:CASCADE;"`
IcalSecret string `gorm:"not null"`
Provider
Token Token `gorm:"foreignKey:UserID; constraint:OnDelete:CASCADE;"`
}

type UserBody struct {
Expand All @@ -81,13 +78,6 @@ type UserBody struct {
User User `gorm:"->; foreignKey:ID; constraint:OnDelete:CASCADE;" cvt:"->"`
}

type RoomAdmin struct {
UserID uuid.UUID `gorm:"type:char(36); primaryKey"`
RoomID uuid.UUID `gorm:"type:char(36); primaryKey"`
User User `gorm:"->; foreignKey:UserID; constraint:OnDelete:CASCADE;" cvt:"->"`
Model `cvt:"-"`
}

//go:generate go run github.com/fuji8/gotypeconverter/cmd/gotypeconverter@latest -s Room -d domain.Room -o converter.go .
//go:generate go run github.com/fuji8/gotypeconverter/cmd/gotypeconverter@latest -s []*Room -d []*domain.Room -o converter.go .
type Room struct {
Expand All @@ -97,7 +87,7 @@ type Room struct {
TimeStart time.Time `gorm:"type:DATETIME; index"`
TimeEnd time.Time `gorm:"type:DATETIME; index"`
Events []Event `gorm:"->; constraint:-"` // readOnly
Admins []RoomAdmin
Admins []User `gorm:"many2many:room_admin_users;"`
CreatedByRefer uuid.UUID `gorm:"type:char(36);" cvt:"CreatedBy, <-"`
CreatedBy User `gorm:"->; foreignKey:CreatedByRefer; constraint:OnDelete:CASCADE;" cvt:"->"`
Model `cvt:"->"`
Expand Down
4 changes: 2 additions & 2 deletions infra/db/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func userPreload(tx *gorm.DB) *gorm.DB {
return tx.Preload("Provider")
return tx
}

func (repo *GormRepository) SaveUser(user User) (*User, error) {
Expand Down Expand Up @@ -73,7 +73,7 @@ func (repo *GormRepository) SyncUsers(users []*User) error {
// user.Privilegeは常に更新されません。
func saveUser(db *gorm.DB, user *User) (*User, error) {
err := db.Transaction(func(tx *gorm.DB) error {
existingUser, err := getUser(tx.Preload("Provider").Preload("Token"), user.ID)
existingUser, err := getUser(tx.Preload("Token"), user.ID)
if errors.Is(err, gorm.ErrRecordNotFound) {
return tx.Create(&user).Error
}
Expand Down
5 changes: 2 additions & 3 deletions infra/db/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ func Test_saveUser(t *testing.T) {
},
},
Provider: Provider{
UserID: id,
Issuer: "bar",
Subject: id.String(),
},
Expand All @@ -29,7 +28,7 @@ func Test_saveUser(t *testing.T) {
t.Run("save user", func(t *testing.T) {
_, err := saveUser(r.db, user)
assert.NoError(err)
u, err := getUser(r.db.Preload("Provider"), id)
u, err := getUser(r.db, id)
assert.NoError(err)
assert.Equal(user.Provider.Issuer, u.Provider.Issuer)
})
Expand All @@ -41,7 +40,7 @@ func Test_saveUser(t *testing.T) {
})
assert.NoError(err)

u, err := getUser(r.db.Preload("Token").Preload("Provider"), id)
u, err := getUser(r.db.Preload("Token"), id)
assert.NoError(err)
// token
assert.Equal(user.Token.AccessToken, u.Token.AccessToken)
Expand Down
2 changes: 2 additions & 0 deletions migration/current.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ func Migrations() []*gormigrate.Migration {
v10(),
v11(),
v12(),
v13(),
v14(),
}
}
67 changes: 67 additions & 0 deletions migration/v13.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package migration

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

type v13newUser struct {
ID uuid.UUID `gorm:"type:char(36); primaryKey"`
Privilege bool `gorm:"not null"`
State int
IcalSecret string `gorm:"not null"`
Issuer string `gorm:"not null"`
Subject string
}

func (*v13newUser) TableName() string {
return "users"
}

type v13currentProvider struct {
UserID uuid.UUID `gorm:"type:char(36); primaryKey"`
Issuer string `gorm:"not null"`
Subject string
}

func (*v13currentProvider) TableName() string {
return "providers"
}

func v13() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "13",
Migrate: func(db *gorm.DB) error {
// Step 1: Add Issuer and Subject columns to the User table
if err := db.Migrator().AddColumn(&v13newUser{}, "Issuer"); err != nil {
return err
}
if err := db.Migrator().AddColumn(&v13newUser{}, "Subject"); err != nil {
return err
}

// Step 2: Migrate data from Provider to User
providers := make([]*v13currentProvider, 0)
if err := db.Find(&providers).Error; err != nil {
return err
}

for _, provider := range providers {
if err := db.Model(&v13newUser{}).Where("id = ?", provider.UserID).Updates(map[string]interface{}{
"Issuer": provider.Issuer,
"Subject": provider.Subject,
}).Error; err != nil {
return err
}
}

// Step 3: Drop the Provider table
if err := db.Migrator().DropTable(&v13currentProvider{}); err != nil {
return err
}

return nil
},
}
}
78 changes: 78 additions & 0 deletions migration/v14.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package migration

import (
"time"

"github.com/go-gormigrate/gormigrate/v2"
"github.com/gofrs/uuid"
"gorm.io/gorm"
)

type v14Room struct {

Check failure on line 11 in migration/v14.go

View workflow job for this annotation

GitHub Actions / Lint

type `v14Room` is unused (unused)
ID uuid.UUID `gorm:"type:char(36);primaryKey"`
Place string `gorm:"type:varchar(32);"`
Verified bool
TimeStart time.Time `gorm:"type:DATETIME; index"`
TimeEnd time.Time `gorm:"type:DATETIME; index"`
CreatedByRefer uuid.UUID `gorm:"type:char(36);"`
}

func (*v14Room) TableName() string {

Check failure on line 20 in migration/v14.go

View workflow job for this annotation

GitHub Actions / Lint

func `(*v14Room).TableName` is unused (unused)
return "rooms"
}

type v14RoomUser struct {
RoomID uuid.UUID `gorm:"type:char(36); primaryKey"`
UserID uuid.UUID `gorm:"type:char(36); primaryKey"`
}

func (*v14RoomUser) TableName() string {
return "room_admin_users"
}

type v14RoomAdmin struct {
UserID uuid.UUID `gorm:"type:char(36); primaryKey"`
RoomID uuid.UUID `gorm:"type:char(36); primaryKey"`
}

func (*v14RoomAdmin) TableName() string {
return "room_admins"
}

func v14() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "14",
Migrate: func(db *gorm.DB) error {
// Step 1: Create the new many-to-many table
err := db.Migrator().CreateTable(&v14RoomUser{})
if err != nil {
return err
}

// Step 2: Migrate data from RoomAdmin to RoomUser
roomAdmins := []v14RoomAdmin{}
err = db.Find(&roomAdmins).Error
if err != nil {
return err
}

roomUsers := make([]v14RoomUser, len(roomAdmins))
for i, admin := range roomAdmins {
roomUsers[i] = v14RoomUser{
RoomID: admin.RoomID,
UserID: admin.UserID,
}
}

if len(roomUsers) > 0 {
err = db.Create(&roomUsers).Error
if err != nil {
return err
}
}

// Step 3: Drop the RoomAdmin table
return db.Migrator().DropTable(&v14RoomAdmin{})
},
}
}
Loading
Loading