Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle https://xorm.io
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.

196 lines
4.7KB

  1. // Copyright 2018 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "database/sql"
  7. "flag"
  8. "fmt"
  9. "log"
  10. "os"
  11. "strings"
  12. "testing"
  13. _ "github.com/denisenkom/go-mssqldb"
  14. _ "github.com/go-sql-driver/mysql"
  15. _ "github.com/lib/pq"
  16. _ "github.com/mattn/go-sqlite3"
  17. _ "github.com/ziutek/mymysql/godrv"
  18. "xorm.io/core"
  19. )
  20. var (
  21. testEngine EngineInterface
  22. dbType string
  23. connString string
  24. db = flag.String("db", "sqlite3", "the tested database")
  25. showSQL = flag.Bool("show_sql", true, "show generated SQLs")
  26. ptrConnStr = flag.String("conn_str", "./test.db?cache=shared&mode=rwc", "test database connection string")
  27. mapType = flag.String("map_type", "snake", "indicate the name mapping")
  28. cache = flag.Bool("cache", false, "if enable cache")
  29. cluster = flag.Bool("cluster", false, "if this is a cluster")
  30. splitter = flag.String("splitter", ";", "the splitter on connstr for cluster")
  31. schema = flag.String("schema", "", "specify the schema")
  32. ignoreSelectUpdate = flag.Bool("ignore_select_update", false, "ignore select update if implementation difference, only for tidb")
  33. tableMapper core.IMapper
  34. colMapper core.IMapper
  35. )
  36. func createEngine(dbType, connStr string) error {
  37. if testEngine == nil {
  38. var err error
  39. if !*cluster {
  40. switch strings.ToLower(dbType) {
  41. case core.MSSQL:
  42. db, err := sql.Open(dbType, strings.Replace(connStr, "xorm_test", "master", -1))
  43. if err != nil {
  44. return err
  45. }
  46. if _, err = db.Exec("If(db_id(N'xorm_test') IS NULL) BEGIN CREATE DATABASE xorm_test; END;"); err != nil {
  47. return fmt.Errorf("db.Exec: %v", err)
  48. }
  49. db.Close()
  50. *ignoreSelectUpdate = true
  51. case core.POSTGRES:
  52. db, err := sql.Open(dbType, connStr)
  53. if err != nil {
  54. return err
  55. }
  56. rows, err := db.Query(fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname = 'xorm_test'"))
  57. if err != nil {
  58. return fmt.Errorf("db.Query: %v", err)
  59. }
  60. defer rows.Close()
  61. if !rows.Next() {
  62. if _, err = db.Exec("CREATE DATABASE xorm_test"); err != nil {
  63. return fmt.Errorf("CREATE DATABASE: %v", err)
  64. }
  65. }
  66. if *schema != "" {
  67. if _, err = db.Exec("CREATE SCHEMA IF NOT EXISTS " + *schema); err != nil {
  68. return fmt.Errorf("CREATE SCHEMA: %v", err)
  69. }
  70. }
  71. db.Close()
  72. *ignoreSelectUpdate = true
  73. case core.MYSQL:
  74. db, err := sql.Open(dbType, strings.Replace(connStr, "xorm_test", "mysql", -1))
  75. if err != nil {
  76. return err
  77. }
  78. if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS xorm_test"); err != nil {
  79. return fmt.Errorf("db.Exec: %v", err)
  80. }
  81. db.Close()
  82. default:
  83. *ignoreSelectUpdate = true
  84. }
  85. testEngine, err = NewEngine(dbType, connStr)
  86. } else {
  87. testEngine, err = NewEngineGroup(dbType, strings.Split(connStr, *splitter))
  88. if dbType != "mysql" && dbType != "mymysql" {
  89. *ignoreSelectUpdate = true
  90. }
  91. }
  92. if err != nil {
  93. return err
  94. }
  95. if *schema != "" {
  96. testEngine.SetSchema(*schema)
  97. }
  98. testEngine.ShowSQL(*showSQL)
  99. testEngine.SetLogLevel(core.LOG_DEBUG)
  100. if *cache {
  101. cacher := NewLRUCacher(NewMemoryStore(), 100000)
  102. testEngine.SetDefaultCacher(cacher)
  103. }
  104. if len(*mapType) > 0 {
  105. switch *mapType {
  106. case "snake":
  107. testEngine.SetMapper(core.SnakeMapper{})
  108. case "same":
  109. testEngine.SetMapper(core.SameMapper{})
  110. case "gonic":
  111. testEngine.SetMapper(core.LintGonicMapper)
  112. }
  113. }
  114. }
  115. tableMapper = testEngine.GetTableMapper()
  116. colMapper = testEngine.GetColumnMapper()
  117. tables, err := testEngine.DBMetas()
  118. if err != nil {
  119. return err
  120. }
  121. var tableNames = make([]interface{}, 0, len(tables))
  122. for _, table := range tables {
  123. tableNames = append(tableNames, table.Name)
  124. }
  125. if err = testEngine.DropTables(tableNames...); err != nil {
  126. return err
  127. }
  128. return nil
  129. }
  130. func prepareEngine() error {
  131. return createEngine(dbType, connString)
  132. }
  133. func TestMain(m *testing.M) {
  134. flag.Parse()
  135. dbType = *db
  136. if *db == "sqlite3" {
  137. if ptrConnStr == nil {
  138. connString = "./test.db?cache=shared&mode=rwc"
  139. } else {
  140. connString = *ptrConnStr
  141. }
  142. } else {
  143. if ptrConnStr == nil {
  144. log.Fatal("you should indicate conn string")
  145. return
  146. }
  147. connString = *ptrConnStr
  148. }
  149. dbs := strings.Split(*db, "::")
  150. conns := strings.Split(connString, "::")
  151. var res int
  152. for i := 0; i < len(dbs); i++ {
  153. dbType = dbs[i]
  154. connString = conns[i]
  155. testEngine = nil
  156. fmt.Println("testing", dbType, connString)
  157. if err := prepareEngine(); err != nil {
  158. log.Fatal(err)
  159. return
  160. }
  161. code := m.Run()
  162. if code > 0 {
  163. res = code
  164. }
  165. }
  166. os.Exit(res)
  167. }
  168. func TestPing(t *testing.T) {
  169. if err := testEngine.Ping(); err != nil {
  170. t.Fatal(err)
  171. }
  172. }