statement_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. package xorm
  2. import (
  3. "reflect"
  4. "sync"
  5. "testing"
  6. "time"
  7. "strings"
  8. "github.com/xormplus/core"
  9. )
  10. var colStrTests = []struct {
  11. omitColumn string
  12. onlyToDBColumnNdx int
  13. expected string
  14. }{
  15. {"", -1, "`ID`, `IsDeleted`, `Caption`, `Code1`, `Code2`, `Code3`, `ParentID`, `Latitude`, `Longitude`"},
  16. {"Code2", -1, "`ID`, `IsDeleted`, `Caption`, `Code1`, `Code3`, `ParentID`, `Latitude`, `Longitude`"},
  17. {"", 1, "`ID`, `Caption`, `Code1`, `Code2`, `Code3`, `ParentID`, `Latitude`, `Longitude`"},
  18. {"Code3", 1, "`ID`, `Caption`, `Code1`, `Code2`, `ParentID`, `Latitude`, `Longitude`"},
  19. {"Longitude", 1, "`ID`, `Caption`, `Code1`, `Code2`, `Code3`, `ParentID`, `Latitude`"},
  20. {"", 8, "`ID`, `IsDeleted`, `Caption`, `Code1`, `Code2`, `Code3`, `ParentID`, `Latitude`"},
  21. }
  22. // !nemec784! Only for Statement object creation
  23. const driverName = "mysql"
  24. const dataSourceName = "Server=TestServer;Database=TestDB;Uid=testUser;Pwd=testPassword;"
  25. func init() {
  26. core.RegisterDriver(driverName, &mysqlDriver{})
  27. }
  28. func TestColumnsStringGeneration(t *testing.T) {
  29. var statement *Statement
  30. for ndx, testCase := range colStrTests {
  31. statement = createTestStatement()
  32. if testCase.omitColumn != "" {
  33. statement.Omit(testCase.omitColumn) // !nemec784! Column must be skipped
  34. }
  35. if testCase.onlyToDBColumnNdx >= 0 {
  36. columns := statement.RefTable.Columns()
  37. columns[testCase.onlyToDBColumnNdx].MapType = core.ONLYTODB // !nemec784! Column must be skipped
  38. }
  39. actual := statement.genColumnStr()
  40. if actual != testCase.expected {
  41. t.Errorf("[test #%d] Unexpected columns string:\nwant:\t%s\nhave:\t%s", ndx, testCase.expected, actual)
  42. }
  43. }
  44. }
  45. func BenchmarkColumnsStringGeneration(b *testing.B) {
  46. b.StopTimer()
  47. statement := createTestStatement()
  48. testCase := colStrTests[0]
  49. if testCase.omitColumn != "" {
  50. statement.Omit(testCase.omitColumn) // !nemec784! Column must be skipped
  51. }
  52. if testCase.onlyToDBColumnNdx >= 0 {
  53. columns := statement.RefTable.Columns()
  54. columns[testCase.onlyToDBColumnNdx].MapType = core.ONLYTODB // !nemec784! Column must be skipped
  55. }
  56. b.StartTimer()
  57. for i := 0; i < b.N; i++ {
  58. actual := statement.genColumnStr()
  59. if actual != testCase.expected {
  60. b.Errorf("Unexpected columns string:\nwant:\t%s\nhave:\t%s", testCase.expected, actual)
  61. }
  62. }
  63. }
  64. func BenchmarkGetFlagForColumnWithICKey_ContainsKey(b *testing.B) {
  65. b.StopTimer()
  66. mapCols := make(map[string]bool)
  67. cols := []*core.Column{
  68. &core.Column{Name: `ID`},
  69. &core.Column{Name: `IsDeleted`},
  70. &core.Column{Name: `Caption`},
  71. &core.Column{Name: `Code1`},
  72. &core.Column{Name: `Code2`},
  73. &core.Column{Name: `Code3`},
  74. &core.Column{Name: `ParentID`},
  75. &core.Column{Name: `Latitude`},
  76. &core.Column{Name: `Longitude`},
  77. }
  78. for _, col := range cols {
  79. mapCols[strings.ToLower(col.Name)] = true
  80. }
  81. b.StartTimer()
  82. for i := 0; i < b.N; i++ {
  83. for _, col := range cols {
  84. if _, ok := getFlagForColumn(mapCols, col); !ok {
  85. b.Fatal("Unexpected result")
  86. }
  87. }
  88. }
  89. }
  90. func BenchmarkGetFlagForColumnWithICKey_EmptyMap(b *testing.B) {
  91. b.StopTimer()
  92. mapCols := make(map[string]bool)
  93. cols := []*core.Column{
  94. &core.Column{Name: `ID`},
  95. &core.Column{Name: `IsDeleted`},
  96. &core.Column{Name: `Caption`},
  97. &core.Column{Name: `Code1`},
  98. &core.Column{Name: `Code2`},
  99. &core.Column{Name: `Code3`},
  100. &core.Column{Name: `ParentID`},
  101. &core.Column{Name: `Latitude`},
  102. &core.Column{Name: `Longitude`},
  103. }
  104. b.StartTimer()
  105. for i := 0; i < b.N; i++ {
  106. for _, col := range cols {
  107. if _, ok := getFlagForColumn(mapCols, col); ok {
  108. b.Fatal("Unexpected result")
  109. }
  110. }
  111. }
  112. }
  113. type TestType struct {
  114. ID int64 `xorm:"ID PK"`
  115. IsDeleted bool `xorm:"IsDeleted"`
  116. Caption string `xorm:"Caption"`
  117. Code1 string `xorm:"Code1"`
  118. Code2 string `xorm:"Code2"`
  119. Code3 string `xorm:"Code3"`
  120. ParentID int64 `xorm:"ParentID"`
  121. Latitude float64 `xorm:"Latitude"`
  122. Longitude float64 `xorm:"Longitude"`
  123. }
  124. func (TestType) TableName() string {
  125. return "TestTable"
  126. }
  127. func createTestStatement() *Statement {
  128. engine := createTestEngine()
  129. statement := &Statement{}
  130. statement.Init()
  131. statement.Engine = engine
  132. statement.setRefValue(reflect.ValueOf(TestType{}))
  133. return statement
  134. }
  135. func createTestEngine() *Engine {
  136. driver := core.QueryDriver(driverName)
  137. uri, err := driver.Parse(driverName, dataSourceName)
  138. if err != nil {
  139. panic(err)
  140. }
  141. dialect := &mysql{}
  142. err = dialect.Init(nil, uri, driverName, dataSourceName)
  143. if err != nil {
  144. panic(err)
  145. }
  146. engine := &Engine{
  147. dialect: dialect,
  148. Tables: make(map[reflect.Type]*core.Table),
  149. mutex: &sync.RWMutex{},
  150. TagIdentifier: "xorm",
  151. TZLocation: time.Local,
  152. }
  153. engine.SetMapper(core.NewCacheMapper(new(core.SnakeMapper)))
  154. return engine
  155. }