sqlx.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. package db
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "sync"
  6. // PostgreSQL
  7. _ "github.com/lib/pq"
  8. // MySQL
  9. _ "github.com/go-sql-driver/mysql"
  10. "github.com/jmoiron/sqlx"
  11. )
  12. // DB db
  13. type DB struct {
  14. Driver string
  15. c *sqlx.DB
  16. tx *sqlx.Tx
  17. }
  18. var (
  19. defaultConfig Option
  20. defaultDb *DB
  21. db *sqlx.DB
  22. once sync.Once
  23. )
  24. // SetDefaultOption default connect option
  25. func SetDefaultOption(opt Option) (err error) {
  26. defaultConfig = opt
  27. defaultDb = &DB{Driver: opt.Driver}
  28. defaultDb.c, err = connect()
  29. return
  30. }
  31. // ReleaseDefault release default connect
  32. func ReleaseDefault() error {
  33. if defaultDb != nil {
  34. if defaultDb.c != nil {
  35. defaultDb.c.Close()
  36. }
  37. }
  38. return nil
  39. }
  40. // New new DB dynamic object
  41. func New(opt Option) (dbx *DB, err error) {
  42. //dbx = &DB{}
  43. dbx.Driver = opt.Driver
  44. dbx.c, err = sqlx.Connect(opt.Driver, opt.DNS)
  45. if err != nil {
  46. return
  47. }
  48. dbx.c.SetMaxOpenConns(opt.MaxOpenConns)
  49. dbx.c.SetMaxIdleConns(opt.MaxIdle)
  50. dbx.c.SetConnMaxLifetime(opt.MaxLifetime)
  51. err = dbx.c.Ping()
  52. return
  53. }
  54. // Release release connect
  55. func Release(dbx *DB) (err error) {
  56. if dbx.c != nil {
  57. err = dbx.c.Close()
  58. }
  59. return
  60. }
  61. func connect() (dbx *sqlx.DB, err error) {
  62. once.Do(func() {
  63. db, err = sqlx.Connect(defaultConfig.Driver, defaultConfig.DNS)
  64. if err == nil {
  65. db.DB.SetMaxOpenConns(defaultConfig.MaxOpenConns)
  66. db.DB.SetMaxIdleConns(defaultConfig.MaxIdle)
  67. db.DB.SetConnMaxLifetime(defaultConfig.MaxLifetime)
  68. err = db.Ping()
  69. }
  70. })
  71. dbx = db
  72. return
  73. }
  74. // Connect connect to database
  75. func (d *DB) Connect() (err error) {
  76. if d.c != nil {
  77. return
  78. }
  79. d.c, err = connect()
  80. return
  81. }
  82. // Close close database connect
  83. func (d *DB) Close() {
  84. // use pool
  85. //d.c.Close()
  86. }
  87. // Ping verifies a connection to the database is still alive, establishing a connection if necessary.
  88. func (d *DB) Ping() error {
  89. return d.c.Ping()
  90. }
  91. // Stats returns database statistics.
  92. func (d *DB) Stats() sql.DBStats {
  93. return d.c.Stats()
  94. }
  95. // BeginTrans begin trans
  96. func (d *DB) BeginTrans() (err error) {
  97. d.c, err = connect()
  98. if err != nil {
  99. return
  100. }
  101. d.tx = d.c.MustBegin()
  102. return
  103. }
  104. // Commit commit
  105. func (d *DB) Commit() error {
  106. return d.tx.Commit()
  107. }
  108. // Rollback rollback
  109. func (d *DB) Rollback() error {
  110. return d.tx.Rollback()
  111. }
  112. // TransNamedExec trans execute
  113. func (d *DB) TransExec(query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  114. rs, err := d.tx.Exec(query, args...)
  115. if err != nil {
  116. return
  117. }
  118. RowsAffected, _ = rs.RowsAffected()
  119. LastInsertId, _ = rs.LastInsertId()
  120. return
  121. }
  122. // TransNamedExec trans execute, named bindvars
  123. func (d *DB) TransNamedExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  124. rs, err := d.tx.NamedExec(query, args)
  125. if err != nil {
  126. return
  127. }
  128. RowsAffected, _ = rs.RowsAffected()
  129. LastInsertId, _ = rs.LastInsertId()
  130. return
  131. }
  132. // TransGet trans get row
  133. func (d *DB) TransGet(dest interface{}, query string, args ...interface{}) (err error) {
  134. d.tx.Get(dest, query, args...)
  135. return
  136. }
  137. // TransNamedGet trans get row, named bindvars
  138. func (d *DB) TransNamedGet(dest interface{}, query string, args interface{}) (err error) {
  139. var nstmt *sqlx.NamedStmt
  140. nstmt, err = d.tx.PrepareNamed(query)
  141. if err != nil {
  142. return
  143. }
  144. defer nstmt.Close()
  145. err = nstmt.Get(dest, args)
  146. return
  147. }
  148. // TransSelect trans get rows
  149. func (d *DB) TransSelect(dest interface{}, query string, args ...interface{}) (err error) {
  150. err = d.tx.Select(dest, query, args...)
  151. return
  152. }
  153. // Get get one
  154. func (d *DB) Get(dest interface{}, query string, args ...interface{}) (err error) {
  155. err = d.Connect()
  156. if err != nil {
  157. return
  158. }
  159. defer d.Close()
  160. err = d.c.Get(dest, query, args...)
  161. return
  162. }
  163. // Get get one, named bindvars
  164. func (d *DB) NamedGet(dest interface{}, query string, args interface{}) (err error) {
  165. err = d.Connect()
  166. if err != nil {
  167. return
  168. }
  169. defer d.Close()
  170. nstmt, err := d.c.PrepareNamed(query)
  171. if err != nil {
  172. return
  173. }
  174. defer nstmt.Close()
  175. err = nstmt.Get(dest, args)
  176. return
  177. }
  178. // Select select rows
  179. func (d *DB) Select(dest interface{}, query string, args ...interface{}) error {
  180. err := d.Connect()
  181. if err != nil {
  182. return err
  183. }
  184. defer d.Close()
  185. err = d.c.Select(dest, query, args...)
  186. return err
  187. }
  188. // NamedSelect select rows, named bindvars
  189. func (d *DB) NamedSelect(dest interface{}, query string, args interface{}) (err error) {
  190. err = d.Connect()
  191. if err != nil {
  192. return err
  193. }
  194. defer d.Close()
  195. nstmt, err := d.c.PrepareNamed(query)
  196. if err != nil {
  197. return err
  198. }
  199. defer nstmt.Close()
  200. err = nstmt.Select(dest, args)
  201. return err
  202. }
  203. // Exec exec
  204. func (d *DB) Exec(query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  205. err = d.Connect()
  206. if err != nil {
  207. return
  208. }
  209. defer d.Close()
  210. var rs sql.Result
  211. rs, err = d.c.Exec(query, args...)
  212. if err != nil {
  213. return
  214. }
  215. LastInsertId, _ = rs.LastInsertId()
  216. RowsAffected, _ = rs.RowsAffected()
  217. return
  218. }
  219. // NamedExec exec, named bindvars
  220. func (d *DB) NamedExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  221. err = d.Connect()
  222. if err != nil {
  223. return
  224. }
  225. defer d.Close()
  226. var rs sql.Result
  227. rs, err = d.c.NamedExec(query, args)
  228. if err != nil {
  229. return
  230. }
  231. LastInsertId, _ = rs.LastInsertId()
  232. RowsAffected, _ = rs.RowsAffected()
  233. return
  234. }
  235. // Limit MySQL/PostgreSQL limit
  236. func (d *DB) Limit(page, pagesize int) string {
  237. // MySQL limit n, size
  238. if d.Driver == DriverMySQL {
  239. return fmt.Sprintf(" LIMIT %d, %d", (page-1)*pagesize, pagesize)
  240. }
  241. // // PostgreSQL limit size offset n
  242. return fmt.Sprintf(" LIMIT %d OFFSET %d", pagesize, (page-1)*pagesize)
  243. }
  244. // Ping verifies a connection to the database is still alive, establishing a connection if necessary.
  245. func Ping() error {
  246. return defaultDb.Ping()
  247. }
  248. // Stats returns database statistics.
  249. func Stats() sql.DBStats {
  250. return defaultDb.Stats()
  251. }
  252. // BeginTrans begin trans
  253. func BeginTrans() (err error) {
  254. return defaultDb.BeginTrans()
  255. }
  256. // Commit commit
  257. func Commit() error {
  258. return defaultDb.Commit()
  259. }
  260. // Rollback rollback
  261. func Rollback() error {
  262. return defaultDb.Rollback()
  263. }
  264. // TransNamedExec trans execute
  265. func TransExec(query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  266. return defaultDb.TransExec(query, args...)
  267. }
  268. // TransNamedExec trans execute, named bindvars
  269. func TransNamedExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  270. return defaultDb.TransNamedExec(query, args)
  271. }
  272. // TransGet trans get row
  273. func TransGet(dest interface{}, query string, args interface{}) (err error) {
  274. return defaultDb.TransGet(dest, query, args)
  275. }
  276. // TransNamedGet trans get row, named bindvars
  277. func TransNamedGet(dest interface{}, query string, args interface{}) (err error) {
  278. return defaultDb.TransNamedGet(dest, query, args)
  279. }
  280. // TransSelect trans get rows
  281. func TransSelect(dest interface{}, query string, args ...interface{}) (err error) {
  282. return defaultDb.TransSelect(dest, query, args...)
  283. }
  284. // Get get one
  285. func Get(dest interface{}, query string, args ...interface{}) error {
  286. return defaultDb.Get(dest, query, args...)
  287. }
  288. // Get get one, named bindvars
  289. func NamedGet(dest interface{}, query string, args interface{}) (err error) {
  290. return defaultDb.NamedGet(dest, query, args)
  291. }
  292. // Select select rows
  293. func Select(dest interface{}, query string, args ...interface{}) error {
  294. return defaultDb.Select(dest, query, args...)
  295. }
  296. // NamedSelect select rows, named bindvars
  297. func NamedSelect(dest interface{}, query string, args interface{}) (err error) {
  298. return defaultDb.NamedSelect(dest, query, args)
  299. }
  300. // Exec execute
  301. func Exec(query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  302. return defaultDb.Exec(query, args...)
  303. }
  304. // NamedExec exec, named bindvars
  305. func NamedExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  306. return defaultDb.NamedExec(query, args)
  307. }
  308. // Limit MySQL/PostgreSQL limit
  309. func Limit(page, pagesize int) string {
  310. return defaultDb.Limit(page, pagesize)
  311. }