common_test.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. package common_test
  2. import (
  3. "fmt"
  4. "io"
  5. "io/ioutil"
  6. "net/url"
  7. "path/filepath"
  8. "testing"
  9. "time"
  10. . "github.com/onsi/ginkgo"
  11. . "github.com/onsi/gomega"
  12. "github.com/vladimirok5959/golang-sql/gosql/common"
  13. )
  14. var _ = Describe("common", func() {
  15. Context("fixQuery", func() {
  16. It("replace param for MySQL driver", func() {
  17. sql := "select id, name from users where id=$1"
  18. Expect(common.FixQuery(sql)).To(Equal("select id, name from users where id=?"))
  19. })
  20. It("replace all params for MySQL driver", func() {
  21. sql := "insert into users set name=$1 where id=$2"
  22. Expect(common.FixQuery(sql)).To(Equal("insert into users set name=? where id=?"))
  23. })
  24. })
  25. Context("insertRow", func() {
  26. It("convert struct to SQL query", func() {
  27. var row struct {
  28. ID int64 `field:"id" table:"users"`
  29. Name string `field:"name"`
  30. Value string `field:"value"`
  31. Position int64 `field:"position"`
  32. }
  33. row.Name = "Name"
  34. row.Value = "Value"
  35. row.Position = 59
  36. sql, args := common.InsertRowString(&row)
  37. Expect(sql).To(Equal(`INSERT INTO users (name, value, position) VALUES ($1, $2, $3)`))
  38. Expect(len(args)).To(Equal(3))
  39. Expect(args[0]).To(Equal("Name"))
  40. Expect(args[1]).To(Equal("Value"))
  41. Expect(args[2]).To(Equal(int64(59)))
  42. })
  43. })
  44. Context("log", func() {
  45. Context("time", func() {
  46. It("calculate one second", func() {
  47. str := common.Log(io.Discard, "Exec", time.Now().Add(time.Second*-1), nil, false, "")
  48. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 1.000 ms\x1b[0m\n"))
  49. })
  50. })
  51. Context("format", func() {
  52. It("with func name", func() {
  53. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "")
  54. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 0.000 ms\x1b[0m\n"))
  55. })
  56. It("with sql query", func() {
  57. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "select * from users")
  58. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] select * from users (empty) (nil) 0.000 ms\x1b[0m\n"))
  59. })
  60. It("with error message", func() {
  61. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), false, "select * from users")
  62. Expect(str).To(Equal("\x1b[0;31m[SQL] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  63. })
  64. It("with transaction flag", func() {
  65. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users")
  66. Expect(str).To(Equal("\x1b[1;31m[SQL] [TX] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  67. })
  68. It("with sql query arguments", func() {
  69. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users where id=$1", 100)
  70. Expect(str).To(Equal("\x1b[1;31m[SQL] [TX] [func Exec] select * from users where id=$1 ([100]) (Exec error) 0.000 ms\x1b[0m\n"))
  71. })
  72. })
  73. })
  74. Context("scans", func() {
  75. It("convert struct to array of pointers to this struct fields", func() {
  76. var row struct {
  77. ID int64
  78. Name string
  79. Value string
  80. }
  81. Expect(common.Scans(&row)).To(Equal([]any{
  82. &row.ID,
  83. &row.Name,
  84. &row.Value,
  85. }))
  86. })
  87. })
  88. Context("queryRowByIDString", func() {
  89. It("convert struct to SQL query", func() {
  90. var row struct {
  91. ID int64 `field:"id" table:"users"`
  92. Name string `field:"name"`
  93. Value string `field:"value"`
  94. }
  95. Expect(common.QueryRowByIDString(&row)).To(Equal(`SELECT id, name, value FROM users WHERE id = $1 LIMIT 1`))
  96. })
  97. })
  98. Context("rowExistsString", func() {
  99. It("convert struct to SQL query", func() {
  100. var row struct {
  101. ID int64 `field:"id" table:"users"`
  102. Name string `field:"name"`
  103. Value string `field:"value"`
  104. }
  105. Expect(common.RowExistsString(&row)).To(Equal(`SELECT 1 FROM users WHERE id = $1 LIMIT 1`))
  106. })
  107. })
  108. Context("deleteRowByIDString", func() {
  109. It("convert struct to SQL query", func() {
  110. var row struct {
  111. ID int64 `field:"id" table:"users"`
  112. Name string `field:"name"`
  113. Value string `field:"value"`
  114. }
  115. Expect(common.DeleteRowByIDString(&row)).To(Equal(`DELETE FROM users WHERE id = $1`))
  116. })
  117. })
  118. Context("ParseUrl", func() {
  119. Context("Success", func() {
  120. It("for MySQL", func() {
  121. // mysql://username:password@127.0.0.1:3306/database?parseTime=true
  122. // mysql://username:password@/database?socket=/var/run/mysqld/mysqld.sock
  123. url := "mysql://username:password@127.0.0.1:3306/database?parseTime=true"
  124. result, err := common.ParseUrl(url)
  125. Expect(err).To(Succeed())
  126. Expect(result.Scheme).To(Equal("mysql"))
  127. Expect(result.User.Username()).To(Equal("username"))
  128. password, whether := result.User.Password()
  129. Expect(password).To(Equal("password"))
  130. Expect(whether).To(BeTrue())
  131. Expect(result.Host).To(Equal("127.0.0.1:3306"))
  132. Expect(result.Path).To(Equal("/database"))
  133. Expect(result.RawQuery).To(Equal("parseTime=true"))
  134. })
  135. It("for PostgreSQL", func() {
  136. // postgres://username:password@127.0.0.1:5432/database?sslmode=disable
  137. // postgresql://username:password@127.0.0.1:5432/database?sslmode=disable
  138. url := "postgres://username:password@127.0.0.1:5432/database?sslmode=disable"
  139. result, err := common.ParseUrl(url)
  140. Expect(err).To(Succeed())
  141. Expect(result.Scheme).To(Equal("postgres"))
  142. Expect(result.User.Username()).To(Equal("username"))
  143. password, whether := result.User.Password()
  144. Expect(password).To(Equal("password"))
  145. Expect(whether).To(BeTrue())
  146. Expect(result.Host).To(Equal("127.0.0.1:5432"))
  147. Expect(result.Path).To(Equal("/database"))
  148. Expect(result.RawQuery).To(Equal("sslmode=disable"))
  149. })
  150. It("for SQLite", func() {
  151. // sqlite:///data/database.sqlite
  152. // sqlite3:///data/database.sqlite
  153. url := "sqlite:///data/database.sqlite"
  154. result, err := common.ParseUrl(url)
  155. Expect(err).To(Succeed())
  156. Expect(result.Scheme).To(Equal("sqlite"))
  157. Expect(result.Host).To(Equal(""))
  158. Expect(result.Path).To(Equal("/data/database.sqlite"))
  159. })
  160. })
  161. Context("Fail", func() {
  162. It("for empty", func() {
  163. _, err := common.ParseUrl("")
  164. Expect(err).NotTo(Succeed())
  165. Expect(err.Error()).To(Equal("protocol scheme is not defined"))
  166. })
  167. It("for else", func() {
  168. url := "12345"
  169. _, err := common.ParseUrl(url)
  170. Expect(err).NotTo(Succeed())
  171. Expect(err.Error()).To(Equal("protocol scheme is not defined"))
  172. })
  173. It("for not supported", func() {
  174. url := "example:///some-else"
  175. _, err := common.ParseUrl(url)
  176. Expect(err).NotTo(Succeed())
  177. Expect(err.Error()).To(Equal("unsupported protocol scheme: example"))
  178. })
  179. })
  180. })
  181. Context("OpenDB", func() {
  182. var migrationsDir string
  183. BeforeEach(func() {
  184. var err error
  185. migrationsDir, err = filepath.Abs("../../db/migrations")
  186. Expect(err).To(Succeed())
  187. })
  188. Context("Success", func() {
  189. // // Note: you need to up MySQL server for this test case
  190. // It("for MySQL", func() {
  191. // databaseURL, err := url.Parse("mysql://root:root@127.0.0.1:3306/gosql")
  192. // Expect(err).To(Succeed())
  193. // db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  194. // Expect(err).To(Succeed())
  195. // Expect(db.Close()).To(Succeed())
  196. // })
  197. // // Note: you need to up PostgreSQL server for this test case
  198. // It("for PostgreSQL", func() {
  199. // databaseURL, err := url.Parse("postgres://root:root@127.0.0.1:5432/gosql?sslmode=disable")
  200. // Expect(err).To(Succeed())
  201. // db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  202. // Expect(err).To(Succeed())
  203. // Expect(db.Close()).To(Succeed())
  204. // })
  205. It("for SQLite", func() {
  206. f, err := ioutil.TempFile("", "go-sqlite3-test-")
  207. Expect(err).To(Succeed())
  208. f.Close()
  209. databaseURL, err := url.Parse("sqlite://" + f.Name())
  210. Expect(err).To(Succeed())
  211. db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  212. Expect(err).To(Succeed())
  213. Expect(db.Close()).To(Succeed())
  214. })
  215. })
  216. })
  217. })
  218. func TestSuite(t *testing.T) {
  219. RegisterFailHandler(Fail)
  220. RunSpecs(t, "gosql/common")
  221. }