db.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. package db
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "sync"
  8. "time"
  9. // PostgreSQL
  10. _ "github.com/lib/pq"
  11. // MySQL
  12. _ "github.com/go-sql-driver/mysql"
  13. "github.com/jmoiron/sqlx"
  14. _ "github.com/mattn/go-sqlite3"
  15. )
  16. var (
  17. config Config
  18. db *sqlx.DB
  19. //err error
  20. once sync.Once
  21. defaultDB *DB
  22. errNoneConnect = errors.New(`数据库连接错误`)
  23. )
  24. // DB define
  25. type DB struct {
  26. Driver string
  27. conn *sqlx.DB
  28. tx *sqlx.Tx
  29. }
  30. // Tx is an in-progress database transaction.
  31. type Tx struct {
  32. tx *sqlx.Tx
  33. }
  34. // SetConfig set
  35. func SetConfig(cfg Config) {
  36. config.Driver = cfg.Driver
  37. config.DNS = cfg.DNS
  38. config.MaxOpenConns = cfg.MaxOpenConns
  39. config.MaxIdle = cfg.MaxIdle
  40. config.MaxIdleTime = cfg.MaxIdleTime * time.Second
  41. config.MaxLifeTime = cfg.MaxLifeTime * time.Second
  42. defaultDB = &DB{Driver: config.Driver}
  43. }
  44. // New new DB object
  45. func New() *DB {
  46. return &DB{Driver: config.Driver}
  47. }
  48. // Release free db connect
  49. func Release() {
  50. if db != nil {
  51. db.Close()
  52. }
  53. }
  54. // NewConfig new DB dynamic object
  55. func NewConfig(config Config) (dbx *DB, err error) {
  56. dbx = &DB{}
  57. dbx.Driver = config.Driver
  58. dbx.conn, err = sqlx.Connect(config.Driver, config.DNS)
  59. if err != nil {
  60. return
  61. }
  62. dbx.conn.SetMaxOpenConns(config.MaxOpenConns)
  63. dbx.conn.SetMaxIdleConns(config.MaxIdle)
  64. dbx.conn.SetConnMaxIdleTime(config.MaxIdleTime)
  65. dbx.conn.SetConnMaxLifetime(config.MaxLifeTime)
  66. //err = dbx.conn.Ping()
  67. return
  68. }
  69. // ReleaseConfig free db connect
  70. func ReleaseConfig(dbx *DB) {
  71. if dbx.conn != nil {
  72. dbx.conn.Close()
  73. }
  74. }
  75. func connect() (dbx *sqlx.DB, err error) {
  76. once.Do(func() {
  77. db, err = sqlx.Connect(config.Driver, config.DNS)
  78. if err != nil {
  79. fmt.Println("Connect ERR", err)
  80. return
  81. }
  82. db.DB.SetMaxOpenConns(config.MaxOpenConns)
  83. db.DB.SetMaxIdleConns(config.MaxIdle)
  84. db.DB.SetConnMaxIdleTime(config.MaxIdleTime)
  85. db.DB.SetConnMaxLifetime(config.MaxLifeTime)
  86. /*
  87. err = db.Ping()
  88. if err != nil {
  89. fmt.Println("Connect Ping", err)
  90. return
  91. }
  92. // */
  93. })
  94. if db == nil {
  95. err = errNoneConnect
  96. return
  97. }
  98. dbx = db
  99. return
  100. }
  101. func connectContext(ctx context.Context) (dbx *sqlx.DB, err error) {
  102. once.Do(func() {
  103. db, err = sqlx.ConnectContext(ctx, config.Driver, config.DNS)
  104. if err != nil {
  105. fmt.Println("Connect ERR", err)
  106. return
  107. }
  108. db.DB.SetMaxOpenConns(config.MaxOpenConns)
  109. db.DB.SetMaxIdleConns(config.MaxIdle)
  110. db.DB.SetConnMaxIdleTime(config.MaxIdleTime)
  111. db.DB.SetConnMaxLifetime(config.MaxLifeTime)
  112. })
  113. if db == nil {
  114. err = errNoneConnect
  115. return
  116. }
  117. dbx = db
  118. return
  119. }
  120. // Stats Stats returns database statistics.
  121. func (d *DB) Stats() (s sql.DBStats) {
  122. s = d.conn.DB.Stats()
  123. return
  124. }
  125. // Connect connect to database
  126. func (d *DB) Connect() (err error) {
  127. if d.conn != nil {
  128. return
  129. }
  130. d.conn, err = connect()
  131. return
  132. }
  133. // ConnectContext connect to database
  134. func (d *DB) ConnectContext(ctx context.Context) (err error) {
  135. if d.conn != nil {
  136. return
  137. }
  138. d.conn, err = connectContext(ctx)
  139. return
  140. }
  141. // Close close database connect
  142. func (d *DB) Close() {
  143. // use pool
  144. //d.conn.Close()
  145. }
  146. // Ping Ping connect
  147. func (d *DB) Ping() (err error) {
  148. d.conn, err = connect()
  149. if err != nil {
  150. return
  151. }
  152. return d.conn.Ping()
  153. }
  154. // PingContext Ping connect
  155. func (d *DB) PingContext(ctx context.Context) (err error) {
  156. d.conn, err = connectContext(ctx)
  157. if err != nil {
  158. return
  159. }
  160. return d.conn.PingContext(ctx)
  161. }
  162. // BeginTrans begin trans
  163. func (d *DB) BeginTrans() (err error) {
  164. d.conn, err = connect()
  165. if err != nil {
  166. return
  167. }
  168. d.tx, err = d.conn.Beginx()
  169. return
  170. }
  171. // Begin starts a transaction. The default isolation level is dependent on the driver.
  172. func (d *DB) Begin() (tx *Tx, err error) {
  173. d.conn, err = connect()
  174. if err != nil {
  175. return
  176. }
  177. tx = &Tx{}
  178. tx.tx, err = d.conn.Beginx()
  179. return
  180. }
  181. // BeginTransx begin trans
  182. func (d *DB) BeginTransx(ctx context.Context, opts *sql.TxOptions) (err error) {
  183. d.conn, err = connectContext(ctx)
  184. if err != nil {
  185. return
  186. }
  187. d.tx, err = d.conn.BeginTxx(ctx, opts)
  188. return
  189. }
  190. // BeginTx starts a transaction.
  191. func (d *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (tx *Tx, err error) {
  192. d.conn, err = connectContext(ctx)
  193. if err != nil {
  194. return
  195. }
  196. tx = &Tx{}
  197. tx.tx, err = d.conn.BeginTxx(ctx, opts)
  198. return
  199. }
  200. // Commit commit
  201. func (d *DB) Commit() (err error) {
  202. return d.tx.Commit()
  203. }
  204. // Rollback rollback
  205. func (d *DB) Rollback() (err error) {
  206. return d.tx.Rollback()
  207. }
  208. // TransExec trans execute with named args
  209. func (d *DB) TransExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  210. if rs, err := d.tx.NamedExec(query, args); err == nil {
  211. RowsAffected, _ = rs.RowsAffected()
  212. LastInsertId, _ = rs.LastInsertId()
  213. }
  214. return
  215. }
  216. // TransExec trans execute with named args
  217. func (d *DB) TransExecContext(ctx context.Context, query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  218. if rs, err := d.tx.NamedExecContext(ctx, query, args); err == nil {
  219. RowsAffected, _ = rs.RowsAffected()
  220. LastInsertId, _ = rs.LastInsertId()
  221. }
  222. return
  223. }
  224. // TransUpdate trans update
  225. func (d *DB) TransUpdate(query string, args interface{}) (reply Reply) {
  226. var (
  227. err error
  228. rs sql.Result
  229. )
  230. if rs, err = d.tx.NamedExec(query, args); err == nil {
  231. a, _ := rs.RowsAffected()
  232. reply = ReplyOk(a, 0)
  233. } else {
  234. reply = ReplyFaild(ErrException, err, errors.New(`数据执行错误`))
  235. }
  236. return
  237. }
  238. // TransRow trans get row
  239. func (d *DB) TransRow(dest interface{}, query string, args interface{}) (err error) {
  240. nstmt, err := d.tx.PrepareNamed(query)
  241. if err != nil {
  242. return err
  243. }
  244. defer nstmt.Close()
  245. err = nstmt.Get(dest, args)
  246. //err = d.tx.Get(dest, query, args)
  247. return err
  248. }
  249. // Select select
  250. func (d *DB) Select(dest interface{}, query string, args ...interface{}) error {
  251. err := d.Connect()
  252. if err != nil {
  253. return err
  254. }
  255. defer d.Close()
  256. err = d.conn.Select(dest, query, args...)
  257. return err
  258. }
  259. // SelectContext select
  260. func (d *DB) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
  261. err := d.ConnectContext(ctx)
  262. if err != nil {
  263. return err
  264. }
  265. defer d.Close()
  266. err = d.conn.SelectContext(ctx, dest, query, args...)
  267. return err
  268. }
  269. // Rows get rows with named args
  270. func (d *DB) Rows(dest interface{}, query string, args interface{}) error {
  271. err := d.Connect()
  272. if err != nil {
  273. return err
  274. }
  275. defer d.Close()
  276. nstmt, err := d.conn.PrepareNamed(query)
  277. if err != nil {
  278. return err
  279. }
  280. defer nstmt.Close()
  281. err = nstmt.Select(dest, args)
  282. return err
  283. }
  284. // RowsContext get rows with named args
  285. func (d *DB) RowsContext(ctx context.Context, dest interface{}, query string, args interface{}) error {
  286. err := d.ConnectContext(ctx)
  287. if err != nil {
  288. return err
  289. }
  290. defer d.Close()
  291. nstmt, err := d.conn.PrepareNamedContext(ctx, query)
  292. if err != nil {
  293. return err
  294. }
  295. defer nstmt.Close()
  296. err = nstmt.SelectContext(ctx, dest, args)
  297. return err
  298. }
  299. // Get get
  300. func (d *DB) Get(dest interface{}, query string, args ...interface{}) error {
  301. err := d.Connect()
  302. if err != nil {
  303. return err
  304. }
  305. defer d.Close()
  306. err = d.conn.Get(dest, query, args...)
  307. return err
  308. }
  309. // GetContext get
  310. func (d *DB) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
  311. err := d.ConnectContext(ctx)
  312. if err != nil {
  313. return err
  314. }
  315. defer d.Close()
  316. err = d.conn.GetContext(ctx, dest, query, args...)
  317. return err
  318. }
  319. // Row get row with named args
  320. func (d *DB) Row(dest interface{}, query string, args interface{}) error {
  321. err := d.Connect()
  322. if err != nil {
  323. return err
  324. }
  325. defer d.Close()
  326. nstmt, err := d.conn.PrepareNamed(query)
  327. if err != nil {
  328. return err
  329. }
  330. defer nstmt.Close()
  331. err = nstmt.Get(dest, args)
  332. return err
  333. }
  334. // RowContext get row with named args
  335. func (d *DB) RowContext(ctx context.Context, dest interface{}, query string, args interface{}) error {
  336. err := d.ConnectContext(ctx)
  337. if err != nil {
  338. return err
  339. }
  340. defer d.Close()
  341. nstmt, err := d.conn.PrepareNamedContext(ctx, query)
  342. if err != nil {
  343. return err
  344. }
  345. defer nstmt.Close()
  346. err = nstmt.GetContext(ctx, dest, args)
  347. return err
  348. }
  349. // InsertReply insert and return DbReply
  350. func (d *DB) InsertReply(query string, args interface{}) (reply Reply) {
  351. var (
  352. err error
  353. rs sql.Result
  354. )
  355. err = d.Connect()
  356. if err != nil {
  357. reply = ReplyFaild(ErrNotConnect, err, errors.New(`数据库连接错误`))
  358. return
  359. }
  360. defer d.Close()
  361. if rs, err = d.conn.NamedExec(query, args); err == nil {
  362. a, _ := rs.RowsAffected()
  363. n, _ := rs.LastInsertId()
  364. reply = ReplyOk(a, n)
  365. } else {
  366. reply = ReplyFaild(ErrException, err, errors.New(`数据执行错误`))
  367. }
  368. return
  369. }
  370. // UpdateReply update/delete and return DbReply
  371. func (d *DB) UpdateReply(query string, args interface{}) (reply Reply) {
  372. var (
  373. err error
  374. rs sql.Result
  375. )
  376. err = d.Connect()
  377. if err != nil {
  378. reply = ReplyFaild(ErrNotConnect, err, errors.New(`数据库连接错误`))
  379. return
  380. }
  381. defer d.Close()
  382. if rs, err = d.conn.NamedExec(query, args); err == nil {
  383. a, _ := rs.RowsAffected()
  384. reply = ReplyOk(a, 0)
  385. } else {
  386. reply = ReplyFaild(ErrException, err, errors.New(`数据执行错误`))
  387. }
  388. return
  389. }
  390. // Insert insert into with named args
  391. func (d *DB) Insert(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  392. err = d.Connect()
  393. if err != nil {
  394. return
  395. }
  396. defer d.Close()
  397. var rs sql.Result
  398. if rs, err = d.conn.NamedExec(query, args); err == nil {
  399. LastInsertId, _ = rs.LastInsertId()
  400. RowsAffected, _ = rs.RowsAffected()
  401. }
  402. return
  403. }
  404. // InsertContext insert into with named args
  405. func (d *DB) InsertContext(ctx context.Context, query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  406. err = d.ConnectContext(ctx)
  407. if err != nil {
  408. return
  409. }
  410. defer d.Close()
  411. var rs sql.Result
  412. if rs, err = d.conn.NamedExecContext(ctx, query, args); err == nil {
  413. LastInsertId, _ = rs.LastInsertId()
  414. RowsAffected, _ = rs.RowsAffected()
  415. }
  416. return
  417. }
  418. // Update update/delete with named args
  419. func (d *DB) Update(query string, args interface{}) (RowsAffected int64, err error) {
  420. err = d.Connect()
  421. if err != nil {
  422. return
  423. }
  424. defer d.Close()
  425. var rs sql.Result
  426. if rs, err = d.conn.NamedExec(query, args); err == nil {
  427. RowsAffected, _ = rs.RowsAffected()
  428. }
  429. return
  430. }
  431. // Update update/delete with named args
  432. func (d *DB) UpdateContext(ctx context.Context, query string, args interface{}) (RowsAffected int64, err error) {
  433. err = d.ConnectContext(ctx)
  434. if err != nil {
  435. return
  436. }
  437. defer d.Close()
  438. var rs sql.Result
  439. if rs, err = d.conn.NamedExecContext(ctx, query, args); err == nil {
  440. RowsAffected, _ = rs.RowsAffected()
  441. }
  442. return
  443. }
  444. // Exec exec
  445. func (d *DB) Exec(query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  446. err = d.Connect()
  447. if err != nil {
  448. return
  449. }
  450. defer d.Close()
  451. var rs sql.Result
  452. if rs, err = d.conn.Exec(query, args...); err == nil {
  453. LastInsertId, _ = rs.LastInsertId()
  454. RowsAffected, _ = rs.RowsAffected()
  455. }
  456. return
  457. }
  458. // ExecContext exec
  459. func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  460. err = d.ConnectContext(ctx)
  461. if err != nil {
  462. return
  463. }
  464. defer d.Close()
  465. var rs sql.Result
  466. if rs, err = d.conn.ExecContext(ctx, query, args...); err == nil {
  467. LastInsertId, _ = rs.LastInsertId()
  468. RowsAffected, _ = rs.RowsAffected()
  469. }
  470. return
  471. }
  472. // Limit MySQL limit
  473. func (d *DB) Limit(page, pagesize int) string {
  474. // MySQL limit 0, size
  475. if d.Driver == `mysql` {
  476. return fmt.Sprintf(" limit %d, %d", (page-1)*pagesize, pagesize)
  477. }
  478. // // PostgreSQL limit size offset 0
  479. return fmt.Sprintf(" limit %d offset %d", pagesize, (page-1)*pagesize)
  480. }
  481. // Commit commits the transaction.
  482. func (t *Tx) Commit() error {
  483. return t.tx.Commit()
  484. }
  485. // Rollback aborts the transaction.
  486. func (t *Tx) Rollback() error {
  487. return t.tx.Rollback()
  488. }
  489. // TransExec trans execute with named args
  490. func (t *Tx) TransExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  491. if rs, err := t.tx.NamedExec(query, args); err == nil {
  492. RowsAffected, _ = rs.RowsAffected()
  493. LastInsertId, _ = rs.LastInsertId()
  494. }
  495. return
  496. }
  497. // Ping ping connect
  498. func Ping() (err error) {
  499. defaultDB.conn, err = connect()
  500. if err != nil {
  501. return
  502. }
  503. err = defaultDB.Ping()
  504. return
  505. }
  506. // PingContext ping connect
  507. func PingContext(ctx context.Context) (err error) {
  508. defaultDB.conn, err = connectContext(ctx)
  509. if err != nil {
  510. return
  511. }
  512. err = defaultDB.PingContext(ctx)
  513. return
  514. }
  515. // Select select
  516. func Select(dest interface{}, query string, args ...interface{}) (err error) {
  517. defaultDB.conn, err = connect()
  518. if err != nil {
  519. return err
  520. }
  521. err = defaultDB.conn.Select(dest, query, args...)
  522. return
  523. }
  524. // Rows get rows with named args
  525. func Rows(dest interface{}, query string, args interface{}) (err error) {
  526. defaultDB.conn, err = connect()
  527. if err != nil {
  528. return err
  529. }
  530. nstmt, err := defaultDB.conn.PrepareNamed(query)
  531. if err != nil {
  532. return
  533. }
  534. defer nstmt.Close()
  535. err = nstmt.Select(dest, args)
  536. return
  537. }
  538. // RowsContext get rows with named args
  539. func RowsContext(ctx context.Context, dest interface{}, query string, args interface{}) (err error) {
  540. defaultDB.conn, err = connectContext(ctx)
  541. if err != nil {
  542. return err
  543. }
  544. nstmt, err := defaultDB.conn.PrepareNamedContext(ctx, query)
  545. if err != nil {
  546. return
  547. }
  548. defer nstmt.Close()
  549. err = nstmt.SelectContext(ctx, dest, args)
  550. return
  551. }
  552. // Get get
  553. func Get(dest interface{}, query string, args ...interface{}) (err error) {
  554. defaultDB.conn, err = connect()
  555. if err != nil {
  556. return
  557. }
  558. err = defaultDB.conn.Get(dest, query, args...)
  559. return
  560. }
  561. // Row get row with named args
  562. func Row(dest interface{}, query string, args interface{}) (err error) {
  563. defaultDB.conn, err = connect()
  564. if err != nil {
  565. return
  566. }
  567. nstmt, err := defaultDB.conn.PrepareNamed(query)
  568. if err != nil {
  569. return err
  570. }
  571. defer nstmt.Close()
  572. err = nstmt.Get(dest, args)
  573. return
  574. }
  575. // RowContext get row with named args
  576. func RowContext(ctx context.Context, dest interface{}, query string, args interface{}) (err error) {
  577. defaultDB.conn, err = connectContext(ctx)
  578. if err != nil {
  579. return
  580. }
  581. nstmt, err := defaultDB.conn.PrepareNamedContext(ctx, query)
  582. if err != nil {
  583. return err
  584. }
  585. defer nstmt.Close()
  586. err = nstmt.GetContext(ctx, dest, args)
  587. return
  588. }
  589. // Exec exec
  590. func Exec(query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  591. defaultDB.conn, err = connect()
  592. if err != nil {
  593. return
  594. }
  595. LastInsertId, RowsAffected, err = defaultDB.Exec(query, args...)
  596. return
  597. }
  598. // Exec exec
  599. func ExecContext(ctx context.Context, query string, args ...interface{}) (LastInsertId, RowsAffected int64, err error) {
  600. defaultDB.conn, err = connectContext(ctx)
  601. if err != nil {
  602. return
  603. }
  604. LastInsertId, RowsAffected, err = defaultDB.ExecContext(ctx, query, args...)
  605. return
  606. }