Browse Source

db warpper

ls 5 years ago
parent
commit
17f4799d68
1 changed files with 346 additions and 0 deletions
  1. 346 0
      db/db.go

+ 346 - 0
db/db.go

@@ -0,0 +1,346 @@
+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)
+}