remove sql.ErrNoRows error for select functions for gdb; improve configuration feature for gdb/glog/gview

This commit is contained in:
John
2019-12-04 16:04:52 +08:00
parent 3e27ea0259
commit be15f85eae
8 changed files with 61 additions and 27 deletions

View File

@ -88,6 +88,7 @@ type DB interface {
GetLastSql() *Sql
PrintQueriedSqls()
SetLogger(logger *glog.Logger)
GetLogger() *glog.Logger
SetMaxIdleConnCount(n int)
SetMaxOpenConnCount(n int)
SetMaxConnLifetime(d time.Duration)
@ -199,7 +200,7 @@ func New(name ...string) (db DB, err error) {
debug: gtype.NewBool(),
cache: gcache.New(),
schema: gtype.NewString(),
logger: glog.DefaultLogger(),
logger: glog.New(),
maxConnLifetime: gDEFAULT_CONN_MAX_LIFE_TIME,
}
switch node.Type {

View File

@ -50,16 +50,16 @@ func (bs *dbBase) GetQueriedSqls() []*Sql {
if bs.sqls == nil {
return nil
}
sqls := make([]*Sql, 0)
array := make([]*Sql, 0)
bs.sqls.Prev()
bs.sqls.RLockIteratorPrev(func(value interface{}) bool {
if value == nil {
return false
}
sqls = append(sqls, value.(*Sql))
array = append(array, value.(*Sql))
return true
})
return sqls
return array
}
// 打印已经执行的SQL列表(仅在debug=true时有效)
@ -219,6 +219,9 @@ func (bs *dbBase) GetStruct(pointer interface{}, query string, args ...interface
if err != nil {
return err
}
if len(one) == 0 {
return sql.ErrNoRows
}
return one.Struct(pointer)
}
@ -228,6 +231,9 @@ func (bs *dbBase) GetStructs(pointer interface{}, query string, args ...interfac
if err != nil {
return err
}
if len(all) == 0 {
return sql.ErrNoRows
}
return all.Structs(pointer)
}
@ -597,7 +603,7 @@ func (bs *dbBase) getCache() *gcache.Cache {
// 将数据查询的列表数据*sql.Rows转换为Result类型
func (bs *dbBase) rowsToResult(rows *sql.Rows) (Result, error) {
if !rows.Next() {
return nil, sql.ErrNoRows
return nil, nil
}
// 列信息列表, 名称与类型
columnTypes, err := rows.ColumnTypes()
@ -631,7 +637,6 @@ func (bs *dbBase) rowsToResult(rows *sql.Rows) (Result, error) {
// 由于 sql.RawBytes 是slice类型, 这里必须使用值复制
v := make([]byte, len(column))
copy(v, column)
//fmt.Println(columns[i], types[i], string(v), v, bs.db.convertValue(v, types[i]))
row[columns[i]] = gvar.New(bs.db.convertValue(v, types[i]))
}
}

View File

@ -119,6 +119,11 @@ func (bs *dbBase) SetLogger(logger *glog.Logger) {
bs.logger = logger
}
// 获得数据库Logger对象
func (bs *dbBase) GetLogger() *glog.Logger {
return bs.logger
}
// 设置数据库连接池中空闲链接的大小
func (bs *dbBase) SetMaxIdleConnCount(n int) {
bs.maxIdleConnCount = n

View File

@ -616,16 +616,22 @@ func (md *Model) Struct(pointer interface{}) error {
if err != nil {
return err
}
if len(one) == 0 {
return sql.ErrNoRows
}
return one.Struct(pointer)
}
// 链式操作查询多条记录并自动转换为指定的slice对象, 如: []struct/[]*struct。
func (md *Model) Structs(pointer interface{}) error {
r, err := md.All()
all, err := md.All()
if err != nil {
return err
}
return r.Structs(pointer)
if len(all) == 0 {
return sql.ErrNoRows
}
return all.Structs(pointer)
}
// 链式操作将结果转换为指定的struct/*struct/[]struct/[]*struct,

View File

@ -28,11 +28,13 @@ import (
)
const (
gFRAME_CORE_COMPONENT_NAME_VIEW = "gf.core.component.view"
gFRAME_CORE_COMPONENT_NAME_REDIS = "gf.core.component.redis"
gFRAME_CORE_COMPONENT_NAME_LOGGER = "gf.core.component.logger"
gFRAME_CORE_COMPONENT_NAME_SERVER = "gf.core.component.server"
gFRAME_CORE_COMPONENT_NAME_VIEWER = "gf.core.component.viewer"
gFRAME_CORE_COMPONENT_NAME_DATABASE = "gf.core.component.database"
gLOGGER_NODE_NAME = "logger"
gVIEWER_NODE_NAME = "viewer"
)
var (
@ -86,17 +88,17 @@ func View(name ...string) *gview.View {
if len(name) > 0 && name[0] != "" {
instanceName = name[0]
}
instanceKey := fmt.Sprintf("%s.%s", gFRAME_CORE_COMPONENT_NAME_VIEW, instanceName)
instanceKey := fmt.Sprintf("%s.%s", gFRAME_CORE_COMPONENT_NAME_VIEWER, instanceName)
return instances.GetOrSetFuncLock(instanceKey, func() interface{} {
view := gview.Instance(instanceName)
// To avoid file no found error while it's not necessary.
if Config().Available() {
var m map[string]interface{}
// It firstly searches the configuration of the instance name.
if m = Config().GetMap(fmt.Sprintf(`viewer.%s`, instanceName)); m == nil {
if m = Config().GetMap(fmt.Sprintf(`%s.%s`, gVIEWER_NODE_NAME, instanceName)); m == nil {
// If the configuration for the instance does not exist,
// it uses the default view configuration.
m = Config().GetMap("viewer")
m = Config().GetMap(gVIEWER_NODE_NAME)
}
if m != nil {
if err := view.SetConfigWithMap(m); err != nil {
@ -140,10 +142,10 @@ func Log(name ...string) *glog.Logger {
if Config().Available() {
var m map[string]interface{}
// It firstly searches the configuration of the instance name.
if m = Config().GetMap(fmt.Sprintf(`logger.%s`, instanceName)); m == nil {
if m = Config().GetMap(fmt.Sprintf(`%s.%s`, gLOGGER_NODE_NAME, instanceName)); m == nil {
// If the configuration for the instance does not exist,
// it uses the default logging configuration.
m = Config().GetMap("logger")
m = Config().GetMap(gLOGGER_NODE_NAME)
}
if m != nil {
if err := logger.SetConfigWithMap(m); err != nil {
@ -208,6 +210,16 @@ func Database(name ...string) gdb.DB {
addConfigMonitor(instanceKey, config)
if db, err := gdb.New(name...); err == nil {
// Initialize logger for ORM.
m := config.GetMap(fmt.Sprintf("database.%s", gLOGGER_NODE_NAME))
if m == nil {
m = config.GetMap(gLOGGER_NODE_NAME)
}
if m != nil {
if err := db.GetLogger().SetConfigWithMap(m); err != nil {
glog.Panic(err)
}
}
return db
} else {
glog.Panic(err)

View File

@ -11,6 +11,7 @@ import (
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/util/gutil"
"io"
"strings"
)
@ -66,14 +67,15 @@ func (l *Logger) SetConfigWithMap(m map[string]interface{}) error {
return errors.New("configuration cannot be empty")
}
// Change string configuration to int value for level.
if v, ok := m["level"]; ok {
switch gconv.String(v) {
levelKey, levelValue := gutil.MapPossibleItemByKey(m, "level")
if levelValue != nil {
switch gconv.String(levelValue) {
case "all":
m["level"] = LEVEL_ALL
m[levelKey] = LEVEL_ALL
case "dev":
m["level"] = LEVEL_DEV
m[levelKey] = LEVEL_DEV
case "prod":
m["level"] = LEVEL_PROD
m[levelKey] = LEVEL_PROD
}
}
config := DefaultConfig()

View File

@ -15,6 +15,7 @@ import (
"github.com/gogf/gf/os/gres"
"github.com/gogf/gf/os/gspath"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/util/gutil"
)
// Config is the configuration object for template engine.
@ -56,8 +57,10 @@ func (view *View) SetConfigWithMap(m map[string]interface{}) error {
return errors.New("configuration cannot be empty")
}
// Most common used configuration support for single view path.
if m["paths"] == nil && m["path"] != nil {
m["paths"] = []interface{}{m["path"]}
k1, v1 := gutil.MapPossibleItemByKey(m, "paths")
_, v2 := gutil.MapPossibleItemByKey(m, "path")
if v1 == nil && v2 != nil {
m[k1] = []interface{}{v2}
}
config := Config{}
err := gconv.Struct(m, &config)

View File

@ -26,23 +26,23 @@ func MapCopy(data map[string]interface{}) (copy map[string]interface{}) {
return
}
// MapValueForPossibleKey tries to find the possible value for given key with or without
// MapPossibleItemByKey tries to find the possible key-value pair for given key with or without
// cases or chars '-'/'_'/'.'/' '.
//
// Note that this function might be of low performance.
func MapPossibleValueForKey(data map[string]interface{}, key string) interface{} {
func MapPossibleItemByKey(data map[string]interface{}, key string) (string, interface{}) {
if v, ok := data[key]; ok {
return v
return key, v
}
replacedKey := replaceCharReg.ReplaceAllString(key, "")
if v, ok := data[replacedKey]; ok {
return v
return replacedKey, v
}
// Loop for check.
for k, v := range data {
if strings.EqualFold(replaceCharReg.ReplaceAllString(k, ""), replacedKey) {
return v
return k, v
}
}
return nil
return "", nil
}