From 9b6936a4fbf4f8ab522788baa407185b6f412a94 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 8 Jul 2020 20:48:29 +0800 Subject: [PATCH] deprecate function DB.Table; improve the configuration node name case-insensitive and ignoring special chars --- database/gdb/gdb.go | 107 ++++++++++++++++++++++++------------ frame/g/g_object.go | 11 +++- frame/gins/gins_database.go | 31 ++++++++--- frame/gins/gins_log.go | 18 +++++- frame/gins/gins_redis.go | 8 ++- frame/gins/gins_server.go | 19 ++++++- frame/gins/gins_view.go | 18 +++++- 7 files changed, 157 insertions(+), 55 deletions(-) diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index c1a78ce39..eb1b191f2 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -25,46 +25,32 @@ import ( // DB defines the interfaces for ORM operations. type DB interface { + // =========================================================================== + // Model creation. + // =========================================================================== + + // Deprecated, use Model instead. The DB interface is designed not only for + // relational databases but also for NoSQL databases in the future. The name + // "Table" is not proper for that purpose any more. + Table(table ...string) *Model + Model(table ...string) *Model + Schema(schema string) *Schema + // Open creates a raw connection object for database with given node configuration. // Note that it is not recommended using the this function manually. Open(config *ConfigNode) (*sql.DB, error) + // =========================================================================== // Query APIs. + // =========================================================================== + Query(sql string, args ...interface{}) (*sql.Rows, error) Exec(sql string, args ...interface{}) (sql.Result, error) Prepare(sql string, execOnMaster ...bool) (*sql.Stmt, error) - // Internal APIs for CURD, which can be overwrote for custom CURD implements. - DoQuery(link Link, sql string, args ...interface{}) (rows *sql.Rows, err error) - DoGetAll(link Link, sql string, args ...interface{}) (result Result, err error) - DoExec(link Link, sql string, args ...interface{}) (result sql.Result, err error) - DoPrepare(link Link, sql string) (*sql.Stmt, error) - DoInsert(link Link, table string, data interface{}, option int, batch ...int) (result sql.Result, err error) - DoBatchInsert(link Link, table string, list interface{}, option int, batch ...int) (result sql.Result, err error) - DoUpdate(link Link, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error) - DoDelete(link Link, table string, condition string, args ...interface{}) (result sql.Result, err error) - - // Query APIs for convenience purpose. - GetAll(sql string, args ...interface{}) (Result, error) - GetOne(sql string, args ...interface{}) (Record, error) - GetValue(sql string, args ...interface{}) (Value, error) - GetArray(sql string, args ...interface{}) ([]Value, error) - GetCount(sql string, args ...interface{}) (int, error) - GetStruct(objPointer interface{}, sql string, args ...interface{}) error - GetStructs(objPointerSlice interface{}, sql string, args ...interface{}) error - GetScan(objPointer interface{}, sql string, args ...interface{}) error - - // Master/Slave specification support. - Master() (*sql.DB, error) - Slave() (*sql.DB, error) - - // Ping-Pong. - PingMaster() error - PingSlave() error - - // Transaction. - Begin() (*TX, error) - Transaction(f func(tx *TX) error) (err error) + // =========================================================================== + // Common APIs for CURD. + // =========================================================================== Insert(table string, data interface{}, batch ...int) (sql.Result, error) InsertIgnore(table string, data interface{}, batch ...int) (sql.Result, error) @@ -78,12 +64,57 @@ type DB interface { Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) - // Model creation. - Table(table ...string) *Model - Model(table ...string) *Model - Schema(schema string) *Schema + // =========================================================================== + // Internal APIs for CURD, which can be overwrote for custom CURD implements. + // =========================================================================== + DoQuery(link Link, sql string, args ...interface{}) (rows *sql.Rows, err error) + DoGetAll(link Link, sql string, args ...interface{}) (result Result, err error) + DoExec(link Link, sql string, args ...interface{}) (result sql.Result, err error) + DoPrepare(link Link, sql string) (*sql.Stmt, error) + DoInsert(link Link, table string, data interface{}, option int, batch ...int) (result sql.Result, err error) + DoBatchInsert(link Link, table string, list interface{}, option int, batch ...int) (result sql.Result, err error) + DoUpdate(link Link, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error) + DoDelete(link Link, table string, condition string, args ...interface{}) (result sql.Result, err error) + + // =========================================================================== + // Query APIs for convenience purpose. + // =========================================================================== + + GetAll(sql string, args ...interface{}) (Result, error) + GetOne(sql string, args ...interface{}) (Record, error) + GetValue(sql string, args ...interface{}) (Value, error) + GetArray(sql string, args ...interface{}) ([]Value, error) + GetCount(sql string, args ...interface{}) (int, error) + GetStruct(objPointer interface{}, sql string, args ...interface{}) error + GetStructs(objPointerSlice interface{}, sql string, args ...interface{}) error + GetScan(objPointer interface{}, sql string, args ...interface{}) error + + // =========================================================================== + // Master/Slave specification support. + // =========================================================================== + + Master() (*sql.DB, error) + Slave() (*sql.DB, error) + + // =========================================================================== + // Ping-Pong. + // =========================================================================== + + PingMaster() error + PingSlave() error + + // =========================================================================== + // Transaction. + // =========================================================================== + + Begin() (*TX, error) + Transaction(f func(tx *TX) error) (err error) + + // =========================================================================== // Configuration methods. + // =========================================================================== + GetCache() *gcache.Cache SetDebug(debug bool) GetDebug() bool @@ -99,7 +130,10 @@ type DB interface { SetMaxOpenConnCount(n int) SetMaxConnLifetime(d time.Duration) + // =========================================================================== // Utility methods. + // =========================================================================== + GetChars() (charLeft string, charRight string) GetMaster(schema ...string) (*sql.DB, error) GetSlave(schema ...string) (*sql.DB, error) @@ -115,7 +149,10 @@ type DB interface { // arguments as you wish before they're committed to driver. HandleSqlBeforeCommit(link Link, sql string, args []interface{}) (string, []interface{}) + // =========================================================================== // Internal methods. + // =========================================================================== + filterFields(schema, table string, data map[string]interface{}) map[string]interface{} convertValue(fieldValue []byte, fieldType string) interface{} rowsToResult(rows *sql.Rows) (Result, error) diff --git a/frame/g/g_object.go b/frame/g/g_object.go index 404fd7abc..99ed724f2 100644 --- a/frame/g/g_object.go +++ b/frame/g/g_object.go @@ -91,13 +91,18 @@ func DB(name ...string) gdb.DB { return gins.Database(name...) } -// Table creates and returns a model from specified database or default database configuration. -// The optional parameter specifies the configuration group name of the database, -// which is "default" in default. +// Deprecated, use Model instead. func Table(tables string, db ...string) *gdb.Model { return DB(db...).Table(tables) } +// Model creates and returns a model from specified database or default database configuration. +// The optional parameter specifies the configuration group name of the database, +// which is "default" in default. +func Model(tables string, db ...string) *gdb.Model { + return DB(db...).Model(tables) +} + // Redis returns an instance of redis client with specified configuration group name. func Redis(name ...string) *gredis.Redis { return gins.Redis(name...) diff --git a/frame/gins/gins_database.go b/frame/gins/gins_database.go index 1a37ea4a1..0904d93b2 100644 --- a/frame/gins/gins_database.go +++ b/frame/gins/gins_database.go @@ -19,6 +19,7 @@ import ( const ( gFRAME_CORE_COMPONENT_NAME_DATABASE = "gf.core.component.database" + gDATABASE_NODE_NAME = "database" ) // Database returns an instance of database ORM object @@ -39,9 +40,15 @@ func Database(name ...string) gdb.DB { } return db } - m := config.GetMap("database") - if m == nil { - panic(`database init failed: "database" node not found, is config file or configuration missing?`) + var m map[string]interface{} + if _, v := gutil.MapPossibleItemByKey( + config.GetMap("."), + gDATABASE_NODE_NAME, + ); v != nil { + m = gconv.Map(v) + } + if len(m) == 0 { + panic(fmt.Sprintf(`database init failed: "%s" node not found, is config file or configuration missing?`, gDATABASE_NODE_NAME)) } // Parse as map-slice and adds it to gdb's global configurations. for group, groupConfig := range m { @@ -78,11 +85,21 @@ func Database(name ...string) gdb.DB { 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) + var m map[string]interface{} + if _, v := gutil.MapPossibleItemByKey( + config.GetMap("."), + fmt.Sprintf("%s.%s", gDATABASE_NODE_NAME, gLOGGER_NODE_NAME), + ); v != nil { + m = gconv.Map(v) + } else { + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + gLOGGER_NODE_NAME, + ); v != nil { + m = gconv.Map(v) + } } - if m != nil { + if len(m) > 0 { if err := db.GetLogger().SetConfigWithMap(m); err != nil { panic(err) } diff --git a/frame/gins/gins_log.go b/frame/gins/gins_log.go index 0b8f21b64..8713c8bd8 100644 --- a/frame/gins/gins_log.go +++ b/frame/gins/gins_log.go @@ -9,6 +9,8 @@ package gins import ( "fmt" "github.com/gogf/gf/os/glog" + "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/util/gutil" ) const ( @@ -30,12 +32,22 @@ 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(`%s.%s`, gLOGGER_NODE_NAME, instanceName)); m == nil { + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + fmt.Sprintf(`%s.%s`, gLOGGER_NODE_NAME, instanceName), + ); v != nil { + m = gconv.Map(v) + } else { // If the configuration for the instance does not exist, // it uses the default logging configuration. - m = Config().GetMap(gLOGGER_NODE_NAME) + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + gLOGGER_NODE_NAME, + ); v != nil { + m = gconv.Map(v) + } } - if m != nil { + if len(m) > 0 { if err := logger.SetConfigWithMap(m); err != nil { panic(err) } diff --git a/frame/gins/gins_redis.go b/frame/gins/gins_redis.go index 9130ae1a4..1d711aafb 100644 --- a/frame/gins/gins_redis.go +++ b/frame/gins/gins_redis.go @@ -10,10 +10,12 @@ import ( "fmt" "github.com/gogf/gf/database/gredis" "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/util/gutil" ) const ( gFRAME_CORE_COMPONENT_NAME_REDIS = "gf.core.component.redis" + gREDIS_NODE_NAME = "redis" ) // Redis returns an instance of redis client with specified configuration group name. @@ -30,7 +32,11 @@ func Redis(name ...string) *gredis.Redis { return gredis.Instance(group) } // Or else, it parses the default configuration file and returns a new redis instance. - if m := config.GetMap("redis"); m != nil { + var m map[string]interface{} + if _, v := gutil.MapPossibleItemByKey(Config().GetMap("."), gREDIS_NODE_NAME); v != nil { + m = gconv.Map(v) + } + if len(m) > 0 { if v, ok := m[group]; ok { redisConfig, err := gredis.ConfigFromStr(gconv.String(v)) if err != nil { diff --git a/frame/gins/gins_server.go b/frame/gins/gins_server.go index 58e7d986c..c42f9e268 100644 --- a/frame/gins/gins_server.go +++ b/frame/gins/gins_server.go @@ -9,10 +9,13 @@ package gins import ( "fmt" "github.com/gogf/gf/net/ghttp" + "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/util/gutil" ) const ( gFRAME_CORE_COMPONENT_NAME_SERVER = "gf.core.component.server" + gSERVER_NODE_NAME = "server" ) // Server returns an instance of http server with specified name. @@ -24,12 +27,22 @@ func Server(name ...interface{}) *ghttp.Server { if Config().Available() { var m map[string]interface{} // It firstly searches the configuration of the instance name. - if m = Config().GetMap(fmt.Sprintf(`server.%s`, s.GetName())); m == nil { + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + fmt.Sprintf(`%s.%s`, gSERVER_NODE_NAME, s.GetName()), + ); v != nil { + m = gconv.Map(v) + } else { // If the configuration for the instance does not exist, // it uses the default server configuration. - m = Config().GetMap("server") + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + gSERVER_NODE_NAME, + ); v != nil { + m = gconv.Map(v) + } } - if m != nil { + if len(m) > 0 { if err := s.SetConfigWithMap(m); err != nil { panic(err) } diff --git a/frame/gins/gins_view.go b/frame/gins/gins_view.go index 05c0d8569..60fae1641 100644 --- a/frame/gins/gins_view.go +++ b/frame/gins/gins_view.go @@ -9,6 +9,8 @@ package gins import ( "fmt" "github.com/gogf/gf/os/gview" + "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/util/gutil" ) const ( @@ -39,12 +41,22 @@ func getViewInstance(name ...string) *gview.View { if Config().Available() { var m map[string]interface{} // It firstly searches the configuration of the instance name. - if m = Config().GetMap(fmt.Sprintf(`%s.%s`, gVIEWER_NODE_NAME, instanceName)); m == nil { + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + fmt.Sprintf(`%s.%s`, gVIEWER_NODE_NAME, instanceName), + ); v != nil { + m = gconv.Map(v) + } else { // If the configuration for the instance does not exist, // it uses the default view configuration. - m = Config().GetMap(gVIEWER_NODE_NAME) + if _, v := gutil.MapPossibleItemByKey( + Config().GetMap("."), + gVIEWER_NODE_NAME, + ); v != nil { + m = gconv.Map(v) + } } - if m != nil { + if len(m) > 0 { if err := view.SetConfigWithMap(m); err != nil { panic(err) }