code.gitea.io/gitea@v1.21.7/models/migrations/v1_15/v181.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package v1_15 //nolint 5 6 import ( 7 "strings" 8 9 "xorm.io/xorm" 10 ) 11 12 func AddPrimaryEmail2EmailAddress(x *xorm.Engine) error { 13 type User struct { 14 ID int64 `xorm:"pk autoincr"` 15 Email string `xorm:"NOT NULL"` 16 IsActive bool `xorm:"INDEX"` // Activate primary email 17 } 18 19 type EmailAddress1 struct { 20 ID int64 `xorm:"pk autoincr"` 21 UID int64 `xorm:"INDEX NOT NULL"` 22 Email string `xorm:"UNIQUE NOT NULL"` 23 LowerEmail string 24 IsActivated bool 25 IsPrimary bool `xorm:"DEFAULT(false) NOT NULL"` 26 } 27 28 // Add lower_email and is_primary columns 29 if err := x.Table("email_address").Sync(new(EmailAddress1)); err != nil { 30 return err 31 } 32 33 if _, err := x.Exec("UPDATE email_address SET lower_email=LOWER(email), is_primary=?", false); err != nil { 34 return err 35 } 36 37 type EmailAddress struct { 38 ID int64 `xorm:"pk autoincr"` 39 UID int64 `xorm:"INDEX NOT NULL"` 40 Email string `xorm:"UNIQUE NOT NULL"` 41 LowerEmail string `xorm:"UNIQUE NOT NULL"` 42 IsActivated bool 43 IsPrimary bool `xorm:"DEFAULT(false) NOT NULL"` 44 } 45 46 // change lower_email as unique 47 if err := x.Sync(new(EmailAddress)); err != nil { 48 return err 49 } 50 51 sess := x.NewSession() 52 defer sess.Close() 53 54 const batchSize = 100 55 56 for start := 0; ; start += batchSize { 57 users := make([]*User, 0, batchSize) 58 if err := sess.Limit(batchSize, start).Find(&users); err != nil { 59 return err 60 } 61 if len(users) == 0 { 62 break 63 } 64 65 for _, user := range users { 66 exist, err := sess.Where("email=?", user.Email).Table("email_address").Exist() 67 if err != nil { 68 return err 69 } 70 if !exist { 71 if _, err := sess.Insert(&EmailAddress{ 72 UID: user.ID, 73 Email: user.Email, 74 LowerEmail: strings.ToLower(user.Email), 75 IsActivated: user.IsActive, 76 IsPrimary: true, 77 }); err != nil { 78 return err 79 } 80 } else { 81 if _, err := sess.Where("email=?", user.Email).Cols("is_primary").Update(&EmailAddress{ 82 IsPrimary: true, 83 }); err != nil { 84 return err 85 } 86 } 87 } 88 } 89 90 return nil 91 }