sqlx.go 8.4 KB

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