改进gdb设计

This commit is contained in:
John
2018-03-12 15:12:38 +08:00
parent bf34f07745
commit e2d205ee09
5 changed files with 61 additions and 83 deletions

View File

@ -11,7 +11,6 @@ import (
"fmt"
"errors"
"database/sql"
"gitee.com/johng/gf/g/os/glog"
"gitee.com/johng/gf/g/os/gcache"
"gitee.com/johng/gf/g/util/grand"
_ "github.com/lib/pq"
@ -75,10 +74,7 @@ type Link interface {
// 内部方法
insert(table string, data Map, option uint8) (sql.Result, error)
batchInsert(table string, list List, batch int, option uint8) (sql.Result, error)
setMaster(master *sql.DB)
setSlave(slave *sql.DB)
setQuoteChar(left string, right string)
setLink(link Link)
getQuoteCharLeft () string
getQuoteCharRight () string
handleSqlBeforeExec(q *string) *string
@ -100,7 +96,7 @@ type Map map[string]interface{}
type List []Map
// 获得默认/指定分组名称的数据库操作对象单例
func Instance (groupName...string) (Link, error) {
func Instance (groupName...string) (*Db, error) {
name := config.d
if len(groupName) > 0 {
name = groupName[0]
@ -109,24 +105,24 @@ func Instance (groupName...string) (Link, error) {
}
// 根据配置项获取一个数据库操作对象单例
func instance (groupName string) (Link, error) {
func instance (groupName string) (*Db, error) {
instanceName := "gdb_instance_" + groupName
result := gcache.Get(instanceName)
if result == nil {
link, err := New(groupName)
db, err := New(groupName)
if err == nil {
gcache.Set(instanceName, link, 0)
return link, nil
gcache.Set(instanceName, db, 0)
return db, nil
} else {
return nil, err
}
} else {
return result.(Link), nil
return result.(*Db), nil
}
}
// 使用默认/指定分组配置进行连接数据库集群配置项default
func New(groupName...string) (Link, error) {
func New(groupName...string) (*Db, error) {
name := config.d
if len(groupName) > 0 {
name = groupName[0]
@ -157,15 +153,15 @@ func New(groupName...string) (Link, error) {
if len(slaveList) > 0 {
slaveNode = getConfigNodeByPriority(&slaveList)
}
return newLink(masterNode, slaveNode)
return newDb(masterNode, slaveNode)
} else {
return nil, errors.New(fmt.Sprintf("empty database configuration for item name '%s'", name))
}
}
// 根据单点数据库配置获得一个数据库草最对象
func NewByNode(node ConfigNode) (Link, error) {
return newLink (&node, nil)
func NewByNode(node ConfigNode) (*Db, error) {
return newDb (&node, nil)
}
// 按照负载均衡算法(优先级配置)从数据库集群中选择一个配置节点出来使用
@ -193,7 +189,7 @@ func getConfigNodeByPriority (cg *ConfigGroup) *ConfigNode {
}
// 创建数据库链接对象
func newLink (masterNode *ConfigNode, slaveNode *ConfigNode) (Link, error) {
func newDb (masterNode *ConfigNode, slaveNode *ConfigNode) (*Db, error) {
var link Link
switch masterNode.Type {
case "mysql":
@ -207,40 +203,25 @@ func newLink (masterNode *ConfigNode, slaveNode *ConfigNode) (Link, error) {
}
master, err := link.Open(masterNode)
if err != nil {
glog.Fatal(err)
return nil, err
}
slave := master
if slaveNode != nil {
slave, err = link.Open(slaveNode)
if err != nil {
glog.Fatal(err)
return nil, err
}
}
link.setLink(link)
link.setMaster(master)
link.setSlave(slave)
link.setQuoteChar(link.getQuoteCharLeft(), link.getQuoteCharRight())
return link, nil
}
// 设置master链接对象
func (db *Db) setMaster(master *sql.DB) {
db.master = master
}
// 设置slave链接对象
func (db *Db) setSlave(slave *sql.DB) {
db.slave = slave
}
// 设置当前数据库类型引用字符
func (db *Db) setQuoteChar(left string, right string) {
db.charl = left
db.charr = right
}
// 设置挡脸操作的link接口
func (db *Db) setLink(link Link) {
db.link = link
//link.setLink(link)
//link.setMaster(master)
//link.setSlave(slave)
//link.setQuoteChar(link.getQuoteCharLeft(), link.getQuoteCharRight())
return &Db {
link : link,
master : master,
slave : slave,
charl : link.getQuoteCharLeft(),
charr : link.getQuoteCharRight(),
}, nil
}

View File

@ -36,8 +36,8 @@ func (db *Db) Close() error {
}
// 数据库sql查询操作主要执行查询
func (db *Db) Query(q string, args ...interface{}) (*sql.Rows, error) {
p := db.link.handleSqlBeforeExec(&q)
func (db *Db) Query(query string, args ...interface{}) (*sql.Rows, error) {
p := db.link.handleSqlBeforeExec(&query)
rows, err := db.slave.Query(*p, args ...)
err = db.formatError(err, p, args...)
if err == nil {
@ -47,20 +47,18 @@ func (db *Db) Query(q string, args ...interface{}) (*sql.Rows, error) {
}
// 执行一条sql并返回执行情况主要用于非查询操作
func (db *Db) Exec(q string, args ...interface{}) (sql.Result, error) {
//fmt.Println(q)
//fmt.Println(args)
p := db.link.handleSqlBeforeExec(&q)
func (db *Db) Exec(query string, args ...interface{}) (sql.Result, error) {
p := db.link.handleSqlBeforeExec(&query)
r, err := db.master.Exec(*p, args ...)
err = db.formatError(err, p, args...)
return r, err
}
// 格式化错误信息
func (db *Db) formatError(err error, q *string, args ...interface{}) error {
func (db *Db) formatError(err error, query *string, args ...interface{}) error {
if err != nil {
errstr := fmt.Sprintf("DB ERROR: %s\n", err.Error())
errstr += fmt.Sprintf("DB QUERY: %s\n", *q)
errstr += fmt.Sprintf("DB QUERY: %s\n", *query)
if len(args) > 0 {
errstr += fmt.Sprintf("DB PARAM: %v\n", args)
}
@ -71,9 +69,9 @@ func (db *Db) formatError(err error, q *string, args ...interface{}) error {
// 数据库查询,获取查询结果集,以列表结构返回
func (db *Db) GetAll(q string, args ...interface{}) (List, error) {
func (db *Db) GetAll(query string, args ...interface{}) (List, error) {
// 执行sql
rows, err := db.Query(q, args ...)
rows, err := db.Query(query, args ...)
if err != nil || rows == nil {
return nil, err
}
@ -104,8 +102,8 @@ func (db *Db) GetAll(q string, args ...interface{}) (List, error) {
}
// 数据库查询,获取查询结果集,以关联数组结构返回
func (db *Db) GetOne(q string, args ...interface{}) (Map, error) {
list, err := db.GetAll(q, args ...)
func (db *Db) GetOne(query string, args ...interface{}) (Map, error) {
list, err := db.GetAll(query, args ...)
if err != nil {
return nil, err
}
@ -113,21 +111,21 @@ func (db *Db) GetOne(q string, args ...interface{}) (Map, error) {
}
// 数据库查询,获取查询字段值
func (db *Db) GetValue(q string, args ...interface{}) (interface{}, error) {
one, err := db.GetOne(q, args ...)
func (db *Db) GetValue(query string, args ...interface{}) (interface{}, error) {
one, err := db.GetOne(query, args ...)
if err != nil {
return "", err
return nil, err
}
for _, v := range one {
return v, nil
}
return "", nil
return nil, nil
}
// sql预处理执行完成后调用返回值sql.Stmt.Exec完成sql操作
// 记得调用sql.Stmt.Close关闭操作对象
func (db *Db) Prepare(q string) (*sql.Stmt, error) {
return db.master.Prepare(q)
func (db *Db) Prepare(query string) (*sql.Stmt, error) {
return db.master.Prepare(query)
}
// ping一下判断或保持数据库链接(master)
@ -155,7 +153,7 @@ func (db *Db) SetMaxOpenConns(n int) {
// 事务操作,开启,会返回一个底层的事务操作对象链接如需要嵌套事务,那么可以使用该对象,否则请忽略
func (db *Db) Begin() (*Tx, error) {
if tx, err := db.master.Begin(); err == nil {
return &Tx{
return &Tx {
db : db,
tx : tx,
}, nil

View File

@ -32,8 +32,8 @@ func (tx *Tx) Rollback() error {
}
// 数据库sql查询操作主要执行查询
func (tx *Tx) Query(q string, args ...interface{}) (*sql.Rows, error) {
p := tx.db.link.handleSqlBeforeExec(&q)
func (tx *Tx) Query(query string, args ...interface{}) (*sql.Rows, error) {
p := tx.db.link.handleSqlBeforeExec(&query)
rows, err := tx.tx.Query(*p, args ...)
err = tx.db.formatError(err, p, args...)
if err == nil {
@ -43,17 +43,17 @@ func (tx *Tx) Query(q string, args ...interface{}) (*sql.Rows, error) {
}
// 执行一条sql并返回执行情况主要用于非查询操作
func (tx *Tx) Exec(q string, args ...interface{}) (sql.Result, error) {
p := tx.db.link.handleSqlBeforeExec(&q)
func (tx *Tx) Exec(query string, args ...interface{}) (sql.Result, error) {
p := tx.db.link.handleSqlBeforeExec(&query)
r, err := tx.tx.Exec(*p, args ...)
err = tx.db.formatError(err, p, args...)
return r, err
}
// 数据库查询,获取查询结果集,以列表结构返回
func (tx *Tx) GetAll(q string, args ...interface{}) (List, error) {
func (tx *Tx) GetAll(query string, args ...interface{}) (List, error) {
// 执行sql
rows, err := tx.Query(q, args ...)
rows, err := tx.Query(query, args ...)
if err != nil || rows == nil {
return nil, err
}
@ -84,8 +84,8 @@ func (tx *Tx) GetAll(q string, args ...interface{}) (List, error) {
}
// 数据库查询,获取查询结果集,以关联数组结构返回
func (tx *Tx) GetOne(q string, args ...interface{}) (Map, error) {
list, err := tx.GetAll(q, args ...)
func (tx *Tx) GetOne(query string, args ...interface{}) (Map, error) {
list, err := tx.GetAll(query, args ...)
if err != nil {
return nil, err
}
@ -93,21 +93,21 @@ func (tx *Tx) GetOne(q string, args ...interface{}) (Map, error) {
}
// 数据库查询,获取查询字段值
func (tx *Tx) GetValue(q string, args ...interface{}) (interface{}, error) {
one, err := tx.GetOne(q, args ...)
func (tx *Tx) GetValue(query string, args ...interface{}) (interface{}, error) {
one, err := tx.GetOne(query, args ...)
if err != nil {
return "", err
return nil, err
}
for _, v := range one {
return v, nil
}
return "", nil
return nil, nil
}
// sql预处理执行完成后调用返回值sql.Stmt.Exec完成sql操作
// 记得调用sql.Stmt.Close关闭操作对象
func (tx *Tx) Prepare(q string) (*sql.Stmt, error) {
return tx.Prepare(q)
func (tx *Tx) Prepare(query string) (*sql.Stmt, error) {
return tx.Prepare(query)
}
// insert、replace, save ignore操作

View File

@ -12,7 +12,6 @@ import (
"strconv"
"gitee.com/johng/gf/g/os/gcfg"
"gitee.com/johng/gf/g/os/gcmd"
"gitee.com/johng/gf/g/os/glog"
"gitee.com/johng/gf/g/os/genv"
"gitee.com/johng/gf/g/os/gview"
"gitee.com/johng/gf/g/os/gfile"
@ -100,14 +99,14 @@ func Config() *gcfg.Config {
}
// 核心对象Database
func Database(names...string) gdb.Link {
func Database(names...string) *gdb.Db {
dbCacheKey := gFRAME_CORE_COMPONENT_NAME_DATABASE
if len(names) > 0 {
dbCacheKey += names[0]
}
result := Get(dbCacheKey)
if result != nil {
return result.(gdb.Link)
return result.(*gdb.Db)
} else {
config := Config()
if config == nil {
@ -155,7 +154,7 @@ func Database(names...string) gdb.Link {
Set(dbCacheKey, db)
return db
} else {
glog.Error(err)
return nil
}
}
}

View File

@ -8,7 +8,7 @@ import (
// 本文件用于gf框架的mysql数据库操作示例不作为单元测试使用
var db gdb.Link
var db *gdb.Db
// 初始化配置及创建数据库
func init () {
@ -455,6 +455,6 @@ func main() {
//linkopUpdate2()
//linkopUpdate3()
//keepPing()
//transaction1()
transaction1()
transaction2()
}