parser_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package parser
  2. import (
  3. "sort"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/tal-tech/go-zero/tools/goctl/model/sql/model"
  7. "github.com/tal-tech/go-zero/tools/goctl/util/stringx"
  8. )
  9. func TestParsePlainText(t *testing.T) {
  10. _, err := Parse("plain text")
  11. assert.NotNil(t, err)
  12. }
  13. func TestParseSelect(t *testing.T) {
  14. _, err := Parse("select * from user")
  15. assert.Equal(t, errUnsupportDDL, err)
  16. }
  17. func TestParseCreateTable(t *testing.T) {
  18. table, err := Parse("CREATE TABLE `test_user` (\n `id` bigint NOT NULL AUTO_INCREMENT,\n `mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `class` bigint NOT NULL,\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,\n `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`),\n UNIQUE KEY `mobile_unique` (`mobile`),\n UNIQUE KEY `class_name_unique` (`class`,`name`),\n KEY `create_index` (`create_time`),\n KEY `name_index` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
  19. assert.Nil(t, err)
  20. assert.Equal(t, "test_user", table.Name.Source())
  21. assert.Equal(t, "id", table.PrimaryKey.Name.Source())
  22. assert.Equal(t, true, table.ContainsTime())
  23. assert.Equal(t, true, func() bool {
  24. mobileUniqueIndex, ok := table.UniqueIndex["mobile_unique"]
  25. if !ok {
  26. return false
  27. }
  28. classNameUniqueIndex, ok := table.UniqueIndex["class_name_unique"]
  29. if !ok {
  30. return false
  31. }
  32. equal := func(f1, f2 []*Field) bool {
  33. sort.Slice(f1, func(i, j int) bool {
  34. return f1[i].Name.Source() < f1[j].Name.Source()
  35. })
  36. sort.Slice(f2, func(i, j int) bool {
  37. return f2[i].Name.Source() < f2[j].Name.Source()
  38. })
  39. if len(f2) != len(f2) {
  40. return false
  41. }
  42. for index, f := range f1 {
  43. if f1[index].Name.Source() != f.Name.Source() {
  44. return false
  45. }
  46. }
  47. return true
  48. }
  49. if !equal(mobileUniqueIndex, []*Field{
  50. {
  51. Name: stringx.From("mobile"),
  52. DataBaseType: "varchar",
  53. DataType: "string",
  54. SeqInIndex: 1,
  55. },
  56. }) {
  57. return false
  58. }
  59. return equal(classNameUniqueIndex, []*Field{
  60. {
  61. Name: stringx.From("class"),
  62. DataBaseType: "bigint",
  63. DataType: "int64",
  64. SeqInIndex: 1,
  65. },
  66. {
  67. Name: stringx.From("name"),
  68. DataBaseType: "varchar",
  69. DataType: "string",
  70. SeqInIndex: 2,
  71. },
  72. })
  73. }())
  74. }
  75. func TestConvertColumn(t *testing.T) {
  76. t.Run("missingPrimaryKey", func(t *testing.T) {
  77. columnData := model.ColumnData{
  78. Db: "user",
  79. Table: "user",
  80. Columns: []*model.Column{
  81. {
  82. DbColumn: &model.DbColumn{
  83. Name: "id",
  84. DataType: "bigint",
  85. },
  86. },
  87. },
  88. }
  89. _, err := columnData.Convert()
  90. assert.NotNil(t, err)
  91. assert.Contains(t, err.Error(), "missing primary key")
  92. })
  93. t.Run("jointPrimaryKey", func(t *testing.T) {
  94. columnData := model.ColumnData{
  95. Db: "user",
  96. Table: "user",
  97. Columns: []*model.Column{
  98. {
  99. DbColumn: &model.DbColumn{
  100. Name: "id",
  101. DataType: "bigint",
  102. },
  103. Index: &model.DbIndex{
  104. IndexName: "PRIMARY",
  105. },
  106. },
  107. {
  108. DbColumn: &model.DbColumn{
  109. Name: "mobile",
  110. DataType: "varchar",
  111. Comment: "手机号",
  112. },
  113. Index: &model.DbIndex{
  114. IndexName: "PRIMARY",
  115. },
  116. },
  117. },
  118. }
  119. _, err := columnData.Convert()
  120. assert.NotNil(t, err)
  121. assert.Contains(t, err.Error(), "joint primary key is not supported")
  122. })
  123. t.Run("normal", func(t *testing.T) {
  124. columnData := model.ColumnData{
  125. Db: "user",
  126. Table: "user",
  127. Columns: []*model.Column{
  128. {
  129. DbColumn: &model.DbColumn{
  130. Name: "id",
  131. DataType: "bigint",
  132. Extra: "auto_increment",
  133. },
  134. Index: &model.DbIndex{
  135. IndexName: "PRIMARY",
  136. SeqInIndex: 1,
  137. },
  138. },
  139. {
  140. DbColumn: &model.DbColumn{
  141. Name: "mobile",
  142. DataType: "varchar",
  143. Comment: "手机号",
  144. },
  145. Index: &model.DbIndex{
  146. IndexName: "mobile_unique",
  147. SeqInIndex: 1,
  148. },
  149. },
  150. },
  151. }
  152. table, err := columnData.Convert()
  153. assert.Nil(t, err)
  154. assert.True(t, table.PrimaryKey.Index.IndexName == "PRIMARY" && table.PrimaryKey.Name == "id")
  155. for _, item := range table.Columns {
  156. if item.Name == "mobile" {
  157. assert.True(t, item.Index.NonUnique == 0)
  158. break
  159. }
  160. }
  161. })
  162. }