migrations.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package migrations
  2. import (
  3. "errors"
  4. "strconv"
  5. "strings"
  6. "time"
  7. "github.com/go-xorm/xorm"
  8. )
  9. type migration func(*xorm.Engine) error
  10. // The version table. Should have only one row with id==1
  11. type Version struct {
  12. Id int64
  13. Version int64
  14. }
  15. // This is a sequence of migrations. Add new migrations to the bottom of the list.
  16. // If you want to "retire" a migration, replace it with "expiredMigration"
  17. var migrations = []migration{
  18. accessToCollaboration,
  19. }
  20. // Migrate database to current version
  21. func Migrate(x *xorm.Engine) error {
  22. if err := x.Sync(new(Version)); err != nil {
  23. return err
  24. }
  25. currentVersion := &Version{Id: 1}
  26. has, err := x.Get(currentVersion)
  27. if err != nil {
  28. return err
  29. } else if !has {
  30. needsMigration, err := x.IsTableExist("user")
  31. if err != nil {
  32. return err
  33. }
  34. if needsMigration {
  35. isEmpty, err := x.IsTableEmpty("user")
  36. if err != nil {
  37. return err
  38. }
  39. needsMigration = !isEmpty
  40. }
  41. if !needsMigration {
  42. currentVersion.Version = int64(len(migrations))
  43. }
  44. if _, err = x.InsertOne(currentVersion); err != nil {
  45. return err
  46. }
  47. }
  48. v := currentVersion.Version
  49. for i, migration := range migrations[v:] {
  50. if err = migration(x); err != nil {
  51. return err
  52. }
  53. currentVersion.Version = v + int64(i) + 1
  54. if _, err = x.Id(1).Update(currentVersion); err != nil {
  55. return err
  56. }
  57. }
  58. return nil
  59. }
  60. func expiredMigration(x *xorm.Engine) error {
  61. return errors.New("You are migrating from a too old gogs version")
  62. }
  63. func mustParseInt64(in []byte) int64 {
  64. i, err := strconv.ParseInt(string(in), 10, 64)
  65. if err != nil {
  66. i = 0
  67. }
  68. return i
  69. }
  70. func accessToCollaboration(x *xorm.Engine) error {
  71. type Collaboration struct {
  72. ID int64 `xorm:"pk autoincr"`
  73. RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
  74. UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
  75. Created time.Time `xorm:"CREATED"`
  76. }
  77. x.Sync(new(Collaboration))
  78. sql := `SELECT u.id AS uid, a.repo_name AS repo, a.mode AS mode FROM access a JOIN user u ON a.user_name=u.lower_name`
  79. results, err := x.Query(sql)
  80. if err != nil {
  81. return err
  82. }
  83. for _, result := range results {
  84. userID := mustParseInt64(result["uid"])
  85. repoRefName := string(result["repo"])
  86. mode := mustParseInt64(result["mode"])
  87. //Collaborators must have write access
  88. if mode < 2 {
  89. continue
  90. }
  91. parts := strings.SplitN(repoRefName, "/", 2)
  92. ownerName := parts[0]
  93. repoName := parts[1]
  94. sql = `SELECT u.id as uid, ou.uid as memberid FROM user u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?`
  95. results, err := x.Query(sql, ownerName)
  96. if err != nil {
  97. return err
  98. }
  99. if len(results) < 1 {
  100. continue
  101. }
  102. ownerID := mustParseInt64(results[0]["uid"])
  103. for _, member := range results {
  104. memberID := mustParseInt64(member["memberid"])
  105. // We can skip all cases that a user is member of the owning organization
  106. if memberID == userID {
  107. continue
  108. }
  109. }
  110. sql = `SELECT id FROM repository WHERE owner_id=? AND lower_name=?`
  111. results, err = x.Query(sql, ownerID, repoName)
  112. if err != nil {
  113. return err
  114. }
  115. if len(results) < 1 {
  116. continue
  117. }
  118. repoID := results[0]["id"]
  119. sql = `INSERT INTO collaboration (user_id, repo_id) VALUES (?,?)`
  120. _, err = x.Exec(sql, userID, repoID)
  121. if err != nil {
  122. return err
  123. }
  124. }
  125. return nil
  126. }