db.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package util
  2. import (
  3. "database/sql"
  4. "errors"
  5. "fmt"
  6. "sync"
  7. "time"
  8. // mysql
  9. _ "github.com/go-sql-driver/mysql"
  10. "github.com/jmoiron/sqlx"
  11. )
  12. const (
  13. // DBErrCodeOK ok
  14. DBErrCodeOK = 0
  15. // DBErrCodeException exception
  16. DBErrCodeException = 1
  17. // DBErrCodeExists exists
  18. DBErrCodeExists = 2
  19. // DBErrCodeNotFound not found
  20. DBErrCodeNotFound = 3
  21. // DBErrCodeAuthorized authorized
  22. DBErrCodeAuthorized = 4
  23. // DBErrCodeNotConnect connect error
  24. DBErrCodeNotConnect = 5
  25. )
  26. // DbConfig config
  27. type DbConfig struct {
  28. Driver string
  29. DNS string
  30. MaxOpenConns int
  31. MaxIdle int
  32. MaxLifetime time.Duration
  33. }
  34. // DbReply db exec return insert/update/delete
  35. type DbReply struct {
  36. OK bool
  37. Err error
  38. LastErr error
  39. ErrCode int
  40. LastID int64
  41. RowsAffected int64
  42. }
  43. // DbReplyToReply db reply to respinse
  44. func DbReplyToReply(reply DbReply) *ReplyData {
  45. status := ErrOk
  46. if !reply.OK {
  47. switch reply.ErrCode {
  48. case DBErrCodeException:
  49. status = ErrException
  50. case DBErrCodeExists:
  51. status = ErrDataExists
  52. case DBErrCodeNotFound:
  53. status = ErrDataNotFound
  54. case DBErrCodeAuthorized:
  55. status = ErrUnAuthorized
  56. case DBErrCodeNotConnect:
  57. status = ErrNotFound
  58. }
  59. return ErrReplyData(status, reply.LastErr.Error())
  60. }
  61. return OkReplyData()
  62. }
  63. var (
  64. config DbConfig
  65. db *sqlx.DB
  66. err error
  67. once sync.Once
  68. )
  69. // DB define
  70. type DB struct {
  71. conn *sqlx.DB
  72. tx *sqlx.Tx
  73. }
  74. // SetDbConfig set
  75. func SetDbConfig(cfg DbConfig) {
  76. config.Driver = cfg.Driver
  77. config.DNS = cfg.DNS
  78. config.MaxOpenConns = cfg.MaxOpenConns
  79. config.MaxIdle = cfg.MaxIdle
  80. config.MaxLifetime = cfg.MaxLifetime * time.Second
  81. }
  82. // ErrSQLNoRows check norows error
  83. func ErrSQLNoRows(err error) bool {
  84. if err == sql.ErrNoRows {
  85. return true
  86. }
  87. return false
  88. }
  89. // DbReplyOk exec ok
  90. func DbReplyOk(rowsAffected, lastID int64) DbReply {
  91. var reply DbReply
  92. reply.OK = true
  93. reply.ErrCode = 0
  94. reply.LastID = lastID
  95. reply.RowsAffected = rowsAffected
  96. return reply
  97. }
  98. // DbReplyFaild exec faild
  99. func DbReplyFaild(errCode int, err, errText error) DbReply {
  100. var reply DbReply
  101. reply.OK = false
  102. reply.ErrCode = errCode
  103. reply.LastID = -1
  104. reply.RowsAffected = -1
  105. reply.Err = err
  106. reply.LastErr = errText
  107. return reply
  108. }
  109. // NewDB new DB object
  110. func NewDB() *DB {
  111. return &DB{}
  112. }
  113. // ReleaseDB free db connect
  114. func ReleaseDB() {
  115. if db != nil {
  116. db.Close()
  117. }
  118. }
  119. // NewConfigDB new DB dynamic object
  120. func NewConfigDB(config DbConfig) (dbx *DB, err error) {
  121. dbx = &DB{}
  122. dbx.conn, err = sqlx.Connect(config.Driver, config.DNS)
  123. if err == nil {
  124. dbx.conn.SetMaxOpenConns(config.MaxOpenConns)
  125. dbx.conn.SetMaxIdleConns(config.MaxIdle)
  126. dbx.conn.SetConnMaxLifetime(config.MaxLifetime)
  127. dbx.conn.Ping()
  128. }
  129. return
  130. }
  131. // ReleaseConfigDB free db connect
  132. func ReleaseConfigDB(dbx *DB) {
  133. if dbx.conn != nil {
  134. dbx.conn.Close()
  135. }
  136. }
  137. func connect() (*sqlx.DB, error) {
  138. if db != nil {
  139. return db, nil
  140. }
  141. //*
  142. var err error
  143. once.Do(func() {
  144. db, err = sqlx.Connect(config.Driver, config.DNS)
  145. if err == nil {
  146. db.DB.SetMaxOpenConns(config.MaxOpenConns)
  147. db.DB.SetMaxIdleConns(config.MaxIdle)
  148. db.DB.SetConnMaxLifetime(config.MaxLifetime)
  149. db.Ping()
  150. }
  151. })
  152. //*/
  153. return db, err
  154. }
  155. // Connect connect to database
  156. func (d *DB) Connect() (err error) {
  157. if d.conn != nil {
  158. return
  159. }
  160. d.conn, err = connect()
  161. return
  162. }
  163. // Close close database connect
  164. func (d *DB) Close() {
  165. //d.conn.Close()
  166. }
  167. // BeginTrans begin trans
  168. func (d *DB) BeginTrans() (err error) {
  169. d.conn, err = connect()
  170. if err != nil {
  171. return
  172. }
  173. d.tx = d.conn.MustBegin()
  174. return
  175. }
  176. // Commit commit
  177. func (d *DB) Commit() error {
  178. return d.tx.Commit()
  179. }
  180. // Rollback rollback
  181. func (d *DB) Rollback() error {
  182. return d.tx.Rollback()
  183. }
  184. // TransExec trans execute
  185. func (d *DB) TransExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  186. if rs, err := d.tx.NamedExec(query, args); err == nil {
  187. RowsAffected, _ = rs.RowsAffected()
  188. LastInsertId, _ = rs.LastInsertId()
  189. }
  190. return
  191. }
  192. // TransUpdate trans update
  193. func (d *DB) TransUpdate(query string, args interface{}) (reply DbReply) {
  194. var (
  195. err error
  196. rs sql.Result
  197. )
  198. if rs, err = d.tx.NamedExec(query, args); err == nil {
  199. a, _ := rs.RowsAffected()
  200. reply = DbReplyOk(a, 0)
  201. } else {
  202. reply = DbReplyFaild(DBErrCodeException, err, errors.New(`数据执行错误`))
  203. }
  204. return
  205. }
  206. // Rows get rows
  207. func (d *DB) Rows(dest interface{}, query string, args interface{}) error {
  208. err := d.Connect()
  209. if err != nil {
  210. return err
  211. }
  212. defer d.Close()
  213. nstmt, err := d.conn.PrepareNamed(query)
  214. if err != nil {
  215. return err
  216. }
  217. defer nstmt.Close()
  218. err = nstmt.Select(dest, args)
  219. return err
  220. }
  221. // Row get row
  222. func (d *DB) Row(dest interface{}, query string, args interface{}) error {
  223. err := d.Connect()
  224. if err != nil {
  225. return err
  226. }
  227. defer d.Close()
  228. nstmt, err := d.conn.PrepareNamed(query)
  229. if err != nil {
  230. return err
  231. }
  232. defer nstmt.Close()
  233. err = nstmt.Get(dest, args)
  234. return err
  235. }
  236. // InsertReply insert and return DbReply
  237. func (d *DB) InsertReply(query string, args interface{}) (reply DbReply) {
  238. var (
  239. err error
  240. rs sql.Result
  241. )
  242. err = d.Connect()
  243. if err != nil {
  244. reply = DbReplyFaild(DBErrCodeNotConnect, err, errors.New(`数据库连接错误`))
  245. return
  246. }
  247. defer d.Close()
  248. if rs, err = d.conn.NamedExec(query, args); err == nil {
  249. a, _ := rs.RowsAffected()
  250. n, _ := rs.LastInsertId()
  251. reply = DbReplyOk(a, n)
  252. } else {
  253. reply = DbReplyFaild(DBErrCodeException, err, errors.New(`数据执行错误`))
  254. }
  255. return
  256. }
  257. // UpdateReply update/delete and return DbReply
  258. func (d *DB) UpdateReply(query string, args interface{}) (reply DbReply) {
  259. var (
  260. err error
  261. rs sql.Result
  262. )
  263. err = d.Connect()
  264. if err != nil {
  265. reply = DbReplyFaild(DBErrCodeNotConnect, err, errors.New(`数据库连接错误`))
  266. return
  267. }
  268. defer d.Close()
  269. if rs, err = d.conn.NamedExec(query, args); err == nil {
  270. a, _ := rs.RowsAffected()
  271. reply = DbReplyOk(a, 0)
  272. } else {
  273. reply = DbReplyFaild(DBErrCodeException, err, errors.New(`数据执行错误`))
  274. }
  275. return
  276. }
  277. // Insert insert into
  278. func (d *DB) Insert(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
  279. err = d.Connect()
  280. if err != nil {
  281. return
  282. }
  283. defer d.Close()
  284. if rs, err := d.conn.NamedExec(query, args); err == nil {
  285. LastInsertId, _ = rs.LastInsertId()
  286. RowsAffected, _ = rs.RowsAffected()
  287. }
  288. return
  289. }
  290. // Update update/delete
  291. func (d *DB) Update(query string, args interface{}) (RowsAffected int64, err error) {
  292. err = d.Connect()
  293. if err != nil {
  294. return
  295. }
  296. defer d.Close()
  297. if rs, err := d.conn.NamedExec(query, args); err == nil {
  298. RowsAffected, _ = rs.RowsAffected()
  299. }
  300. return
  301. }
  302. // Limit MySQL limit
  303. func (d *DB) Limit(page, pagesize int) string {
  304. return fmt.Sprintf(" limit %d, %d", (page-1)*pagesize, pagesize)
  305. }