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.

sequence.go 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package db
  4. import (
  5. "context"
  6. "fmt"
  7. "regexp"
  8. "code.gitea.io/gitea/modules/setting"
  9. )
  10. // CountBadSequences looks for broken sequences from recreate-table mistakes
  11. func CountBadSequences(_ context.Context) (int64, error) {
  12. if !setting.Database.Type.IsPostgreSQL() {
  13. return 0, nil
  14. }
  15. sess := x.NewSession()
  16. defer sess.Close()
  17. var sequences []string
  18. schema := x.Dialect().URI().Schema
  19. sess.Engine().SetSchema("")
  20. if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE 'tmp_recreate__%_id_seq%' AND sequence_catalog = ?", setting.Database.Name).Find(&sequences); err != nil {
  21. return 0, err
  22. }
  23. sess.Engine().SetSchema(schema)
  24. return int64(len(sequences)), nil
  25. }
  26. // FixBadSequences fixes for broken sequences from recreate-table mistakes
  27. func FixBadSequences(_ context.Context) error {
  28. if !setting.Database.Type.IsPostgreSQL() {
  29. return nil
  30. }
  31. sess := x.NewSession()
  32. defer sess.Close()
  33. if err := sess.Begin(); err != nil {
  34. return err
  35. }
  36. var sequences []string
  37. schema := sess.Engine().Dialect().URI().Schema
  38. sess.Engine().SetSchema("")
  39. if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE 'tmp_recreate__%_id_seq%' AND sequence_catalog = ?", setting.Database.Name).Find(&sequences); err != nil {
  40. return err
  41. }
  42. sess.Engine().SetSchema(schema)
  43. sequenceRegexp := regexp.MustCompile(`tmp_recreate__(\w+)_id_seq.*`)
  44. for _, sequence := range sequences {
  45. tableName := sequenceRegexp.FindStringSubmatch(sequence)[1]
  46. newSequenceName := tableName + "_id_seq"
  47. if _, err := sess.Exec(fmt.Sprintf("ALTER SEQUENCE `%s` RENAME TO `%s`", sequence, newSequenceName)); err != nil {
  48. return err
  49. }
  50. if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', COALESCE((SELECT MAX(id)+1 FROM `%s`), 1), false)", newSequenceName, tableName)); err != nil {
  51. return err
  52. }
  53. }
  54. return sess.Commit()
  55. }