123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- package db
- import (
- "database/sql"
- "errors"
- "fmt"
- "sync"
- "time"
- "git.chuangxin1.com/cx/tyr"
- // mysql
- _ "github.com/go-sql-driver/mysql"
- "github.com/jmoiron/sqlx"
- )
- // DB error code
- const (
- DBErrCodeOK = 0 // DBErrCodeOK ok
- DBErrCodeException = 1 // DBErrCodeException exception
- DBErrCodeExists = 2 // DBErrCodeExists exists
- DBErrCodeNotFound = 3 // DBErrCodeNotFound not found
- DBErrCodeAuthorized = 4 // DBErrCodeAuthorized authorized
- DBErrCodeNotConnect = 5 // DBErrCodeNotConnect connect error
- )
- // Config config
- type Config struct {
- Driver string
- DNS string
- MaxOpenConns int
- MaxIdle int
- MaxLifetime time.Duration
- }
- // Reply db exec return insert/update/delete
- type Reply struct {
- OK bool
- Err error
- LastErr error
- ErrCode int
- LastID int64
- RowsAffected int64
- }
- // ReplyToReplyData db reply to response
- func ReplyToReplyData(reply Reply) *tyr.ReplyData {
- status := tyr.ErrOk
- if !reply.OK {
- switch reply.ErrCode {
- case DBErrCodeException:
- status = tyr.ErrException
- case DBErrCodeExists:
- status = tyr.ErrDataExists
- case DBErrCodeNotFound:
- status = tyr.ErrDataNotFound
- case DBErrCodeAuthorized:
- status = tyr.ErrUnAuthorized
- case DBErrCodeNotConnect:
- status = tyr.ErrNotFound
- }
- return tyr.ErrReplyData(status, reply.LastErr.Error())
- }
- return tyr.OkReplyData()
- }
- var (
- config Config
- db *sqlx.DB
- err error
- once sync.Once
- )
- // DB define
- type DB struct {
- conn *sqlx.DB
- tx *sqlx.Tx
- }
- // SetDbConfig set
- func SetDbConfig(cfg Config) {
- config.Driver = cfg.Driver
- config.DNS = cfg.DNS
- config.MaxOpenConns = cfg.MaxOpenConns
- config.MaxIdle = cfg.MaxIdle
- config.MaxLifetime = cfg.MaxLifetime * time.Second
- }
- // ErrSQLNoRows check norows error
- func ErrSQLNoRows(err error) bool {
- if err == sql.ErrNoRows {
- return true
- }
- return false
- }
- // ReplyOk exec ok
- func ReplyOk(rowsAffected, lastID int64) Reply {
- var reply Reply
- reply.OK = true
- reply.ErrCode = 0
- reply.LastID = lastID
- reply.RowsAffected = rowsAffected
- return reply
- }
- // ReplyFaild exec faild
- func ReplyFaild(errCode int, err, errText error) (reply Reply) {
- reply.OK = false
- reply.ErrCode = errCode
- reply.LastID = -1
- reply.RowsAffected = -1
- reply.Err = err
- reply.LastErr = errText
- return
- }
- // NewDB new DB object
- func NewDB() *DB {
- return &DB{}
- }
- // ReleaseDB free db connect
- func ReleaseDB() {
- if db != nil {
- db.Close()
- }
- }
- // NewConfigDB new DB dynamic object
- func NewConfigDB(config Config) (dbx *DB, err error) {
- dbx = &DB{}
- dbx.conn, err = sqlx.Connect(config.Driver, config.DNS)
- if err == nil {
- dbx.conn.SetMaxOpenConns(config.MaxOpenConns)
- dbx.conn.SetMaxIdleConns(config.MaxIdle)
- dbx.conn.SetConnMaxLifetime(config.MaxLifetime)
- dbx.conn.Ping()
- }
- return
- }
- // ReleaseConfigDB free db connect
- func ReleaseConfigDB(dbx *DB) {
- if dbx.conn != nil {
- dbx.conn.Close()
- }
- }
- func connect() (dbx *sqlx.DB, err error) {
- once.Do(func() {
- db, err = sqlx.Connect(config.Driver, config.DNS)
- if err == nil {
- db.DB.SetMaxOpenConns(config.MaxOpenConns)
- db.DB.SetMaxIdleConns(config.MaxIdle)
- db.DB.SetConnMaxLifetime(config.MaxLifetime)
- db.Ping()
- }
- })
- dbx = db
- return
- }
- // Connect connect to database
- func (d *DB) Connect() (err error) {
- if d.conn != nil {
- return
- }
- d.conn, err = connect()
- return
- }
- // Close close database connect
- func (d *DB) Close() {
- //d.conn.Close()
- }
- // BeginTrans begin trans
- func (d *DB) BeginTrans() (err error) {
- d.conn, err = connect()
- if err != nil {
- return
- }
- d.tx = d.conn.MustBegin()
- return
- }
- // Commit commit
- func (d *DB) Commit() error {
- return d.tx.Commit()
- }
- // Rollback rollback
- func (d *DB) Rollback() error {
- return d.tx.Rollback()
- }
- // TransExec trans execute
- func (d *DB) TransExec(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
- if rs, err := d.tx.NamedExec(query, args); err == nil {
- RowsAffected, _ = rs.RowsAffected()
- LastInsertId, _ = rs.LastInsertId()
- }
- return
- }
- // TransUpdate trans update
- func (d *DB) TransUpdate(query string, args interface{}) (reply Reply) {
- var (
- err error
- rs sql.Result
- )
- if rs, err = d.tx.NamedExec(query, args); err == nil {
- a, _ := rs.RowsAffected()
- reply = ReplyOk(a, 0)
- } else {
- reply = ReplyFaild(DBErrCodeException, err, errors.New(`数据执行错误`))
- }
- return
- }
- // Rows get rows
- func (d *DB) Rows(dest interface{}, query string, args interface{}) error {
- err := d.Connect()
- if err != nil {
- return err
- }
- defer d.Close()
- nstmt, err := d.conn.PrepareNamed(query)
- if err != nil {
- return err
- }
- defer nstmt.Close()
- err = nstmt.Select(dest, args)
- return err
- }
- // Row get row
- func (d *DB) Row(dest interface{}, query string, args interface{}) error {
- err := d.Connect()
- if err != nil {
- return err
- }
- defer d.Close()
- nstmt, err := d.conn.PrepareNamed(query)
- if err != nil {
- return err
- }
- defer nstmt.Close()
- err = nstmt.Get(dest, args)
- return err
- }
- // InsertReply insert and return DbReply
- func (d *DB) InsertReply(query string, args interface{}) (reply Reply) {
- var (
- err error
- rs sql.Result
- )
- err = d.Connect()
- if err != nil {
- reply = ReplyFaild(DBErrCodeNotConnect, err, errors.New(`数据库连接错误`))
- return
- }
- defer d.Close()
- if rs, err = d.conn.NamedExec(query, args); err == nil {
- a, _ := rs.RowsAffected()
- n, _ := rs.LastInsertId()
- reply = ReplyOk(a, n)
- } else {
- reply = ReplyFaild(DBErrCodeException, err, errors.New(`数据执行错误`))
- }
- return
- }
- // UpdateReply update/delete and return DbReply
- func (d *DB) UpdateReply(query string, args interface{}) (reply Reply) {
- var (
- err error
- rs sql.Result
- )
- err = d.Connect()
- if err != nil {
- reply = ReplyFaild(DBErrCodeNotConnect, err, errors.New(`数据库连接错误`))
- return
- }
- defer d.Close()
- if rs, err = d.conn.NamedExec(query, args); err == nil {
- a, _ := rs.RowsAffected()
- reply = ReplyOk(a, 0)
- } else {
- reply = ReplyFaild(DBErrCodeException, err, errors.New(`数据执行错误`))
- }
- return
- }
- // Insert insert into
- func (d *DB) Insert(query string, args interface{}) (LastInsertId, RowsAffected int64, err error) {
- err = d.Connect()
- if err != nil {
- return
- }
- defer d.Close()
- if rs, err := d.conn.NamedExec(query, args); err == nil {
- LastInsertId, _ = rs.LastInsertId()
- RowsAffected, _ = rs.RowsAffected()
- }
- return
- }
- // Update update/delete
- func (d *DB) Update(query string, args interface{}) (RowsAffected int64, err error) {
- err = d.Connect()
- if err != nil {
- return
- }
- defer d.Close()
- if rs, err := d.conn.NamedExec(query, args); err == nil {
- RowsAffected, _ = rs.RowsAffected()
- }
- return
- }
- // Limit MySQL limit
- func (d *DB) Limit(page, pagesize int) string {
- return fmt.Sprintf(" limit %d, %d", (page-1)*pagesize, pagesize)
- }
|