common_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. It("convert struct to SQL query and populate created_at and updated_at", func() {
  54. var row struct {
  55. ID int64 `field:"id" table:"users"`
  56. CreatedAt int64 `field:"created_at"`
  57. UpdatedAt int64 `field:"updated_at"`
  58. Name string `field:"name"`
  59. }
  60. row.Name = "Name"
  61. sql, args := common.InsertRowString(&row)
  62. Expect(sql).To(Equal(`INSERT INTO users (created_at, updated_at, name) VALUES ($1, $2, $3)`))
  63. Expect(len(args)).To(Equal(3))
  64. Expect(args[0].(int64) > 0).To(BeTrue())
  65. Expect(args[1].(int64) > 0).To(BeTrue())
  66. Expect(args[2]).To(Equal("Name"))
  67. })
  68. })
  69. Context("log", func() {
  70. Context("time", func() {
  71. It("calculate one second", func() {
  72. str := common.Log(io.Discard, "Exec", time.Now().Add(time.Second*-1), nil, false, "")
  73. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 1.000 ms\x1b[0m\n"))
  74. })
  75. })
  76. Context("format", func() {
  77. It("with func name", func() {
  78. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "")
  79. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 0.000 ms\x1b[0m\n"))
  80. })
  81. It("with sql query", func() {
  82. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "select * from users")
  83. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] select * from users (empty) (nil) 0.000 ms\x1b[0m\n"))
  84. })
  85. It("with error message", func() {
  86. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), false, "select * from users")
  87. Expect(str).To(Equal("\x1b[0;31m[SQL] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  88. })
  89. It("with transaction flag", func() {
  90. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users")
  91. Expect(str).To(Equal("\x1b[1;31m[SQL] [TX] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  92. })
  93. It("with sql query arguments", func() {
  94. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users where id=$1", 100)
  95. 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"))
  96. })
  97. })
  98. })
  99. Context("queryRowByIDString", func() {
  100. It("convert struct to SQL query", func() {
  101. var row struct {
  102. ID int64 `field:"id" table:"users"`
  103. Name string `field:"name"`
  104. Value string `field:"value"`
  105. }
  106. Expect(common.QueryRowByIDString(&row)).To(Equal(`SELECT id, name, value FROM users WHERE id = $1 LIMIT 1`))
  107. })
  108. })
  109. Context("rowExistsString", func() {
  110. It("convert struct to SQL query", func() {
  111. var row struct {
  112. ID int64 `field:"id" table:"users"`
  113. Name string `field:"name"`
  114. Value string `field:"value"`
  115. }
  116. Expect(common.RowExistsString(&row)).To(Equal(`SELECT 1 FROM users WHERE id = $1 LIMIT 1`))
  117. })
  118. })
  119. Context("scans", func() {
  120. It("convert struct to array of pointers to this struct fields", func() {
  121. var row struct {
  122. ID int64
  123. Name string
  124. Value string
  125. }
  126. Expect(common.Scans(&row)).To(Equal([]any{
  127. &row.ID,
  128. &row.Name,
  129. &row.Value,
  130. }))
  131. })
  132. })
  133. Context("ParseUrl", func() {
  134. Context("Success", func() {
  135. It("for MySQL", func() {
  136. // mysql://username:password@127.0.0.1:3306/database?parseTime=true
  137. // mysql://username:password@/database?socket=/var/run/mysqld/mysqld.sock
  138. url := "mysql://username:password@127.0.0.1:3306/database?parseTime=true"
  139. result, err := common.ParseUrl(url)
  140. Expect(err).To(Succeed())
  141. Expect(result.Scheme).To(Equal("mysql"))
  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:3306"))
  147. Expect(result.Path).To(Equal("/database"))
  148. Expect(result.RawQuery).To(Equal("parseTime=true"))
  149. })
  150. It("for PostgreSQL", func() {
  151. // postgres://username:password@127.0.0.1:5432/database?sslmode=disable
  152. // postgresql://username:password@127.0.0.1:5432/database?sslmode=disable
  153. url := "postgres://username:password@127.0.0.1:5432/database?sslmode=disable"
  154. result, err := common.ParseUrl(url)
  155. Expect(err).To(Succeed())
  156. Expect(result.Scheme).To(Equal("postgres"))
  157. Expect(result.User.Username()).To(Equal("username"))
  158. password, whether := result.User.Password()
  159. Expect(password).To(Equal("password"))
  160. Expect(whether).To(BeTrue())
  161. Expect(result.Host).To(Equal("127.0.0.1:5432"))
  162. Expect(result.Path).To(Equal("/database"))
  163. Expect(result.RawQuery).To(Equal("sslmode=disable"))
  164. })
  165. It("for SQLite", func() {
  166. // sqlite:///data/database.sqlite
  167. // sqlite3:///data/database.sqlite
  168. url := "sqlite:///data/database.sqlite"
  169. result, err := common.ParseUrl(url)
  170. Expect(err).To(Succeed())
  171. Expect(result.Scheme).To(Equal("sqlite"))
  172. Expect(result.Host).To(Equal(""))
  173. Expect(result.Path).To(Equal("/data/database.sqlite"))
  174. })
  175. })
  176. Context("Fail", func() {
  177. It("for empty", func() {
  178. _, err := common.ParseUrl("")
  179. Expect(err).NotTo(Succeed())
  180. Expect(err.Error()).To(Equal("protocol scheme is not defined"))
  181. })
  182. It("for else", func() {
  183. url := "12345"
  184. _, err := common.ParseUrl(url)
  185. Expect(err).NotTo(Succeed())
  186. Expect(err.Error()).To(Equal("protocol scheme is not defined"))
  187. })
  188. It("for not supported", func() {
  189. url := "example:///some-else"
  190. _, err := common.ParseUrl(url)
  191. Expect(err).NotTo(Succeed())
  192. Expect(err.Error()).To(Equal("unsupported protocol scheme: example"))
  193. })
  194. })
  195. })
  196. Context("OpenDB", func() {
  197. var migrationsDir string
  198. BeforeEach(func() {
  199. var err error
  200. migrationsDir, err = filepath.Abs("../../db/migrations")
  201. Expect(err).To(Succeed())
  202. })
  203. Context("Success", func() {
  204. // // Note: you need to up MySQL server for this test case
  205. // It("for MySQL", func() {
  206. // databaseURL, err := url.Parse("mysql://root:root@127.0.0.1:3306/gosql")
  207. // Expect(err).To(Succeed())
  208. // db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  209. // Expect(err).To(Succeed())
  210. // Expect(db.Close()).To(Succeed())
  211. // })
  212. // // Note: you need to up PostgreSQL server for this test case
  213. // It("for PostgreSQL", func() {
  214. // databaseURL, err := url.Parse("postgres://root:root@127.0.0.1:5432/gosql?sslmode=disable")
  215. // Expect(err).To(Succeed())
  216. // db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  217. // Expect(err).To(Succeed())
  218. // Expect(db.Close()).To(Succeed())
  219. // })
  220. It("for SQLite", func() {
  221. f, err := ioutil.TempFile("", "go-sqlite3-test-")
  222. Expect(err).To(Succeed())
  223. f.Close()
  224. databaseURL, err := url.Parse("sqlite://" + f.Name())
  225. Expect(err).To(Succeed())
  226. db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  227. Expect(err).To(Succeed())
  228. Expect(db.Close()).To(Succeed())
  229. })
  230. })
  231. })
  232. })
  233. func TestSuite(t *testing.T) {
  234. RegisterFailHandler(Fail)
  235. RunSpecs(t, "gosql/common")
  236. }