common_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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("inArray", func() {
  36. It("check string in array", func() {
  37. arr := []string{"field1", "field2", "field3"}
  38. Expect(common.InArray(arr, "field1")).To(BeTrue())
  39. Expect(common.InArray(arr, "field2")).To(BeTrue())
  40. Expect(common.InArray(arr, "field3")).To(BeTrue())
  41. Expect(common.InArray(arr, "field4")).To(BeFalse())
  42. Expect(common.InArray(arr, "field5")).To(BeFalse())
  43. })
  44. })
  45. Context("insertRowString", func() {
  46. It("convert struct to SQL query", func() {
  47. var row struct {
  48. ID int64 `field:"id" table:"users"`
  49. Name string `field:"name"`
  50. Value string `field:"value"`
  51. Position int64 `field:"position"`
  52. }
  53. row.Name = "Name"
  54. row.Value = "Value"
  55. row.Position = 59
  56. sql, args := common.InsertRowString(&row)
  57. Expect(sql).To(Equal(`INSERT INTO users (name, value, position) VALUES ($1, $2, $3)`))
  58. Expect(len(args)).To(Equal(3))
  59. Expect(args[0]).To(Equal("Name"))
  60. Expect(args[1]).To(Equal("Value"))
  61. Expect(args[2]).To(Equal(int64(59)))
  62. })
  63. It("convert struct to SQL query and populate created_at and updated_at", func() {
  64. var row struct {
  65. ID int64 `field:"id" table:"users"`
  66. CreatedAt int64 `field:"created_at"`
  67. UpdatedAt int64 `field:"updated_at"`
  68. Name string `field:"name"`
  69. }
  70. row.Name = "Name"
  71. sql, args := common.InsertRowString(&row)
  72. Expect(sql).To(Equal(`INSERT INTO users (created_at, updated_at, name) VALUES ($1, $2, $3)`))
  73. Expect(len(args)).To(Equal(3))
  74. Expect(args[0].(int64) > 0).To(BeTrue())
  75. Expect(args[1].(int64) > 0).To(BeTrue())
  76. Expect(args[2]).To(Equal("Name"))
  77. })
  78. })
  79. Context("log", func() {
  80. Context("time", func() {
  81. It("calculate one second", func() {
  82. str := common.Log(io.Discard, "Exec", time.Now().Add(time.Second*-1), nil, false, "")
  83. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 1.000 ms\x1b[0m\n"))
  84. })
  85. })
  86. Context("format", func() {
  87. It("with func name", func() {
  88. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "")
  89. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] (empty) (nil) 0.000 ms\x1b[0m\n"))
  90. })
  91. It("with sql query", func() {
  92. str := common.Log(io.Discard, "Exec", time.Now(), nil, false, "select * from users")
  93. Expect(str).To(Equal("\x1b[0;33m[SQL] [func Exec] select * from users (empty) (nil) 0.000 ms\x1b[0m\n"))
  94. })
  95. It("with error message", func() {
  96. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), false, "select * from users")
  97. Expect(str).To(Equal("\x1b[0;31m[SQL] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  98. })
  99. It("with transaction flag", func() {
  100. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users")
  101. Expect(str).To(Equal("\x1b[1;31m[SQL] [TX] [func Exec] select * from users (empty) (Exec error) 0.000 ms\x1b[0m\n"))
  102. })
  103. It("with sql query arguments", func() {
  104. str := common.Log(io.Discard, "Exec", time.Now(), fmt.Errorf("Exec error"), true, "select * from users where id=$1", 100)
  105. 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"))
  106. })
  107. })
  108. })
  109. Context("queryRowByIDString", 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.QueryRowByIDString(&row)).To(Equal(`SELECT id, name, value FROM users WHERE id = $1 LIMIT 1`))
  117. })
  118. })
  119. Context("rowExistsString", func() {
  120. It("convert struct to SQL query", func() {
  121. var row struct {
  122. ID int64 `field:"id" table:"users"`
  123. Name string `field:"name"`
  124. Value string `field:"value"`
  125. }
  126. Expect(common.RowExistsString(&row)).To(Equal(`SELECT 1 FROM users WHERE id = $1 LIMIT 1`))
  127. })
  128. })
  129. Context("scans", func() {
  130. It("convert struct to array of pointers to this struct fields", func() {
  131. var row struct {
  132. ID int64
  133. Name string
  134. Value string
  135. }
  136. Expect(common.Scans(&row)).To(Equal([]any{
  137. &row.ID,
  138. &row.Name,
  139. &row.Value,
  140. }))
  141. })
  142. })
  143. Context("updateRowString", func() {
  144. It("convert struct to SQL query", func() {
  145. var row struct {
  146. ID int64 `field:"id" table:"users"`
  147. Name string `field:"name"`
  148. Value string `field:"value"`
  149. Position int64 `field:"position"`
  150. }
  151. row.ID = 10
  152. row.Name = "Name"
  153. row.Value = "Value"
  154. row.Position = 59
  155. sql, args := common.UpdateRowString(&row)
  156. Expect(sql).To(Equal(`UPDATE users SET name = $1, value = $2, position = $3 WHERE id = $4`))
  157. Expect(len(args)).To(Equal(4))
  158. Expect(args[0]).To(Equal("Name"))
  159. Expect(args[1]).To(Equal("Value"))
  160. Expect(args[2]).To(Equal(int64(59)))
  161. Expect(args[3]).To(Equal(int64(10)))
  162. sql, args = common.UpdateRowString(&row, "name")
  163. Expect(sql).To(Equal(`UPDATE users SET name = $1 WHERE id = $2`))
  164. Expect(len(args)).To(Equal(2))
  165. Expect(args[0]).To(Equal("Name"))
  166. Expect(args[1]).To(Equal(int64(10)))
  167. sql, args = common.UpdateRowString(&row, "name", "value")
  168. Expect(sql).To(Equal(`UPDATE users SET name = $1, value = $2 WHERE id = $3`))
  169. Expect(len(args)).To(Equal(3))
  170. Expect(args[0]).To(Equal("Name"))
  171. Expect(args[1]).To(Equal("Value"))
  172. Expect(args[2]).To(Equal(int64(10)))
  173. sql, args = common.UpdateRowString(&row, "name", "position")
  174. Expect(sql).To(Equal(`UPDATE users SET name = $1, position = $2 WHERE id = $3`))
  175. Expect(len(args)).To(Equal(3))
  176. Expect(args[0]).To(Equal("Name"))
  177. Expect(args[1]).To(Equal(int64(59)))
  178. Expect(args[2]).To(Equal(int64(10)))
  179. })
  180. It("convert struct to SQL query and populate updated_at", func() {
  181. var row struct {
  182. ID int64 `field:"id" table:"users"`
  183. CreatedAt int64 `field:"created_at"`
  184. UpdatedAt int64 `field:"updated_at"`
  185. Name string `field:"name"`
  186. }
  187. row.ID = 10
  188. row.Name = "Name"
  189. sql, args := common.UpdateRowString(&row)
  190. Expect(sql).To(Equal(`UPDATE users SET updated_at = $1, name = $2 WHERE id = $3`))
  191. Expect(len(args)).To(Equal(3))
  192. Expect(args[0].(int64) > 0).To(BeTrue())
  193. Expect(args[1]).To(Equal("Name"))
  194. Expect(args[2]).To(Equal(int64(10)))
  195. })
  196. })
  197. Context("ParseUrl", func() {
  198. Context("Success", func() {
  199. It("for MySQL", func() {
  200. // mysql://username:password@127.0.0.1:3306/database?parseTime=true
  201. // mysql://username:password@/database?socket=/var/run/mysqld/mysqld.sock
  202. url := "mysql://username:password@127.0.0.1:3306/database?parseTime=true"
  203. result, err := common.ParseUrl(url)
  204. Expect(err).To(Succeed())
  205. Expect(result.Scheme).To(Equal("mysql"))
  206. Expect(result.User.Username()).To(Equal("username"))
  207. password, whether := result.User.Password()
  208. Expect(password).To(Equal("password"))
  209. Expect(whether).To(BeTrue())
  210. Expect(result.Host).To(Equal("127.0.0.1:3306"))
  211. Expect(result.Path).To(Equal("/database"))
  212. Expect(result.RawQuery).To(Equal("parseTime=true"))
  213. })
  214. It("for PostgreSQL", func() {
  215. // postgres://username:password@127.0.0.1:5432/database?sslmode=disable
  216. // postgresql://username:password@127.0.0.1:5432/database?sslmode=disable
  217. url := "postgres://username:password@127.0.0.1:5432/database?sslmode=disable"
  218. result, err := common.ParseUrl(url)
  219. Expect(err).To(Succeed())
  220. Expect(result.Scheme).To(Equal("postgres"))
  221. Expect(result.User.Username()).To(Equal("username"))
  222. password, whether := result.User.Password()
  223. Expect(password).To(Equal("password"))
  224. Expect(whether).To(BeTrue())
  225. Expect(result.Host).To(Equal("127.0.0.1:5432"))
  226. Expect(result.Path).To(Equal("/database"))
  227. Expect(result.RawQuery).To(Equal("sslmode=disable"))
  228. })
  229. It("for SQLite", func() {
  230. // sqlite:///data/database.sqlite
  231. // sqlite3:///data/database.sqlite
  232. url := "sqlite:///data/database.sqlite"
  233. result, err := common.ParseUrl(url)
  234. Expect(err).To(Succeed())
  235. Expect(result.Scheme).To(Equal("sqlite"))
  236. Expect(result.Host).To(Equal(""))
  237. Expect(result.Path).To(Equal("/data/database.sqlite"))
  238. })
  239. })
  240. Context("Fail", func() {
  241. It("for empty", func() {
  242. _, err := common.ParseUrl("")
  243. Expect(err).NotTo(Succeed())
  244. Expect(err.Error()).To(Equal("protocol scheme is not defined"))
  245. })
  246. It("for else", func() {
  247. url := "12345"
  248. _, err := common.ParseUrl(url)
  249. Expect(err).NotTo(Succeed())
  250. Expect(err.Error()).To(Equal("protocol scheme is not defined"))
  251. })
  252. It("for not supported", func() {
  253. url := "example:///some-else"
  254. _, err := common.ParseUrl(url)
  255. Expect(err).NotTo(Succeed())
  256. Expect(err.Error()).To(Equal("unsupported protocol scheme: example"))
  257. })
  258. })
  259. })
  260. Context("OpenDB", func() {
  261. var migrationsDir string
  262. BeforeEach(func() {
  263. var err error
  264. migrationsDir, err = filepath.Abs("../../db/migrations")
  265. Expect(err).To(Succeed())
  266. })
  267. Context("Success", func() {
  268. // // Note: you need to up MySQL server for this test case
  269. // It("for MySQL", func() {
  270. // databaseURL, err := url.Parse("mysql://root:root@127.0.0.1:3306/gosql")
  271. // Expect(err).To(Succeed())
  272. // db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  273. // Expect(err).To(Succeed())
  274. // Expect(db.Close()).To(Succeed())
  275. // })
  276. // // Note: you need to up PostgreSQL server for this test case
  277. // It("for PostgreSQL", func() {
  278. // databaseURL, err := url.Parse("postgres://root:root@127.0.0.1:5432/gosql?sslmode=disable")
  279. // Expect(err).To(Succeed())
  280. // db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  281. // Expect(err).To(Succeed())
  282. // Expect(db.Close()).To(Succeed())
  283. // })
  284. It("for SQLite", func() {
  285. f, err := ioutil.TempFile("", "go-sqlite3-test-")
  286. Expect(err).To(Succeed())
  287. f.Close()
  288. databaseURL, err := url.Parse("sqlite://" + f.Name())
  289. Expect(err).To(Succeed())
  290. db, err := common.OpenDB(databaseURL, migrationsDir, false, false)
  291. Expect(err).To(Succeed())
  292. Expect(db.Close()).To(Succeed())
  293. })
  294. })
  295. })
  296. })
  297. func TestSuite(t *testing.T) {
  298. RegisterFailHandler(Fail)
  299. RunSpecs(t, "gosql/common")
  300. }