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("deleteRowByIDString", func() {
  16. It("convert struct to SQL query", func() {
  17. var row struct {
  18. ID int64 `field:"id" table:"users"`
  19. Name string `field:"name"`
  20. Value string `field:"value"`
  21. }
  22. Expect(common.DeleteRowByIDString(&row)).To(Equal(`DELETE FROM users WHERE id = $1`))
  23. })
  24. })
  25. Context("fixQuery", func() {
  26. It("replace param for MySQL driver", func() {
  27. sql := "select id, name from users where id=$1"
  28. Expect(common.FixQuery(sql)).To(Equal("select id, name from users where id=?"))
  29. })
  30. It("replace all params for MySQL driver", func() {
  31. sql := "insert into users set name=$1 where id=$2"
  32. Expect(common.FixQuery(sql)).To(Equal("insert into users set name=? where id=?"))
  33. })
  34. })
  35. Context("insertRow", func() {
  36. It("convert struct to SQL query", func() {
  37. var row struct {
  38. ID int64 `field:"id" table:"users"`
  39. Name string `field:"name"`
  40. Value string `field:"value"`
  41. Position int64 `field:"position"`
  42. }
  43. row.Name = "Name"
  44. row.Value = "Value"
  45. row.Position = 59
  46. sql, args := common.InsertRowString(&row)
  47. Expect(sql).To(Equal(`INSERT INTO users (name, value, position) VALUES ($1, $2, $3)`))
  48. Expect(len(args)).To(Equal(3))
  49. Expect(args[0]).To(Equal("Name"))
  50. Expect(args[1]).To(Equal("Value"))
  51. Expect(args[2]).To(Equal(int64(59)))
  52. })
  53. })
  54. Context("log", func() {
  55. Context("time", func() {
  56. It("calculate one second", func() {
  57. str := common.Log(io.Discard, "Exec", time.Now().Add(time.Second*-1), nil, false, "")
  58. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 1.000 ms\x1b[0m\n"))
  59. })
  60. })
  61. Context("format", func() {
  62. It("with func name", func() {
  63. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "")
  64. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 0.000 ms\x1b[0m\n"))
  65. })
  66. It("with sql query", func() {
  67. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "select * from users")
  68. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] select * from users (empty) (nil) 0.000 ms\x1b[0m\n"))
  69. })
  70. It("with error message", func() {
  71. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), false, "select * from users")
  72. Expect(str).To(Equal("\x1b[0;31m[SQL] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  73. })
  74. It("with transaction flag", func() {
  75. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users")
  76. Expect(str).To(Equal("\x1b[1;31m[SQL] [TX] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  77. })
  78. It("with sql query arguments", func() {
  79. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users where id=$1", 100)
  80. 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"))
  81. })
  82. })
  83. })
  84. Context("queryRowByIDString", func() {
  85. It("convert struct to SQL query", func() {
  86. var row struct {
  87. ID int64 `field:"id" table:"users"`
  88. Name string `field:"name"`
  89. Value string `field:"value"`
  90. }
  91. Expect(common.QueryRowByIDString(&row)).To(Equal(`SELECT id, name, value FROM users WHERE id = $1 LIMIT 1`))
  92. })
  93. })
  94. Context("rowExistsString", func() {
  95. It("convert struct to SQL query", func() {
  96. var row struct {
  97. ID int64 `field:"id" table:"users"`
  98. Name string `field:"name"`
  99. Value string `field:"value"`
  100. }
  101. Expect(common.RowExistsString(&row)).To(Equal(`SELECT 1 FROM users WHERE id = $1 LIMIT 1`))
  102. })
  103. })
  104. Context("scans", func() {
  105. It("convert struct to array of pointers to this struct fields", func() {
  106. var row struct {
  107. ID int64
  108. Name string
  109. Value string
  110. }
  111. Expect(common.Scans(&row)).To(Equal([]any{
  112. &row.ID,
  113. &row.Name,
  114. &row.Value,
  115. }))
  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. }