You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.4 KiB

  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package migrations
  5. import (
  6. "fmt"
  7. "code.gitea.io/gitea/modules/setting"
  8. "xorm.io/xorm"
  9. )
  10. func increaseLanguageField(x *xorm.Engine) error {
  11. type LanguageStat struct {
  12. RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
  13. Language string `xorm:"VARCHAR(50) UNIQUE(s) INDEX NOT NULL"`
  14. }
  15. if err := x.Sync2(new(LanguageStat)); err != nil {
  16. return err
  17. }
  18. if setting.Database.UseSQLite3 {
  19. // SQLite maps VARCHAR to TEXT without size so we're done
  20. return nil
  21. }
  22. // need to get the correct type for the new column
  23. inferredTable, err := x.TableInfo(new(LanguageStat))
  24. if err != nil {
  25. return err
  26. }
  27. column := inferredTable.GetColumn("language")
  28. sqlType := x.Dialect().SQLType(column)
  29. sess := x.NewSession()
  30. defer sess.Close()
  31. if err := sess.Begin(); err != nil {
  32. return err
  33. }
  34. switch {
  35. case setting.Database.UseMySQL:
  36. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat MODIFY COLUMN language %s", sqlType)); err != nil {
  37. return err
  38. }
  39. case setting.Database.UseMSSQL:
  40. // Yet again MSSQL just has to be awkward.
  41. // Here we have to drop the constraints first and then rebuild them
  42. constraints := make([]string, 0)
  43. if err := sess.SQL(`SELECT i.name AS Name
  44. FROM sys.indexes i INNER JOIN sys.index_columns ic
  45. ON i.index_id = ic.index_id AND i.object_id = ic.object_id
  46. INNER JOIN sys.tables AS t
  47. ON t.object_id = i.object_id
  48. INNER JOIN sys.columns c
  49. ON t.object_id = c.object_id AND ic.column_id = c.column_id
  50. WHERE t.name = 'language_stat' AND c.name = 'language'`).Find(&constraints); err != nil {
  51. return fmt.Errorf("Find constraints: %v", err)
  52. }
  53. for _, constraint := range constraints {
  54. if _, err := sess.Exec(fmt.Sprintf("DROP INDEX [%s] ON `language_stat`", constraint)); err != nil {
  55. return fmt.Errorf("Drop table `language_stat` constraint `%s`: %v", constraint, err)
  56. }
  57. }
  58. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language %s", sqlType)); err != nil {
  59. return err
  60. }
  61. // Finally restore the constraint
  62. if err := sess.CreateUniques(new(LanguageStat)); err != nil {
  63. return err
  64. }
  65. case setting.Database.UsePostgreSQL:
  66. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language TYPE %s", sqlType)); err != nil {
  67. return err
  68. }
  69. }
  70. return sess.Commit()
  71. }