improve support for dynamic database configurations in codes

This commit is contained in:
Jack 2020-08-31 15:39:27 +08:00
parent f54593037b
commit a7c269886b
3 changed files with 60 additions and 38 deletions

View File

@ -283,10 +283,10 @@ func Register(name string, driver Driver) error {
// New creates and returns an ORM object with global configurations.
// The parameter <name> specifies the configuration group name,
// which is DEFAULT_GROUP_NAME in default.
func New(name ...string) (db DB, err error) {
group := configs.group
if len(name) > 0 && name[0] != "" {
group = name[0]
func New(group ...string) (db DB, err error) {
groupName := configs.group
if len(group) > 0 && group[0] != "" {
groupName = group[0]
}
configs.RLock()
defer configs.RUnlock()
@ -294,10 +294,10 @@ func New(name ...string) (db DB, err error) {
if len(configs.config) < 1 {
return nil, errors.New("empty database configuration")
}
if _, ok := configs.config[group]; ok {
if node, err := getConfigNodeByGroup(group, true); err == nil {
if _, ok := configs.config[groupName]; ok {
if node, err := getConfigNodeByGroup(groupName, true); err == nil {
c := &Core{
group: group,
group: groupName,
debug: gtype.NewBool(),
cache: gcache.New(),
schema: gtype.NewString(),
@ -320,7 +320,7 @@ func New(name ...string) (db DB, err error) {
return nil, err
}
} else {
return nil, errors.New(fmt.Sprintf(`database configuration node "%s" is not found`, group))
return nil, errors.New(fmt.Sprintf(`database configuration node "%s" is not found`, groupName))
}
}

View File

@ -115,6 +115,14 @@ func GetDefaultGroup() string {
return configs.group
}
// IsConfigured checks and returns whether the database configured.
// It returns true if any configuration exists.
func IsConfigured() bool {
configs.RLock()
defer configs.RUnlock()
return len(configs.config) > 0
}
// SetLogger sets the logger for orm.
func (c *Core) SetLogger(logger *glog.Logger) {
c.logger = logger

View File

@ -31,26 +31,26 @@ func Database(name ...string) gdb.DB {
}
instanceKey := fmt.Sprintf("%s.%s", gFRAME_CORE_COMPONENT_NAME_DATABASE, group)
db := instances.GetOrSetFuncLock(instanceKey, func() interface{} {
// If configuration file does not exist but the gdb configurations are already set.
if !Config().Available() && gdb.GetConfig(group) != nil {
db, err := gdb.Instance(group)
if err != nil {
panic(err)
}
return db
}
// Check the configuration file.
var m map[string]interface{}
var (
configMap map[string]interface{}
configNodeKey string
)
// It firstly searches the configuration of the instance name.
nodeKey, _ := gutil.MapPossibleItemByKey(Config().GetMap("."), gDATABASE_NODE_NAME)
if nodeKey == "" {
nodeKey = gDATABASE_NODE_NAME
if Config().Available() {
configNodeKey, _ = gutil.MapPossibleItemByKey(Config().GetMap("."), gDATABASE_NODE_NAME)
if configNodeKey == "" {
configNodeKey = gDATABASE_NODE_NAME
}
configMap = Config().GetMap(configNodeKey)
}
if m = Config().GetMap(nodeKey); len(m) == 0 {
if len(configMap) == 0 && !gdb.IsConfigured() {
panic(fmt.Sprintf(`database init failed: "%s" node not found, is config file or configuration missing?`, gDATABASE_NODE_NAME))
}
if len(configMap) == 0 {
configMap = make(map[string]interface{})
}
// Parse <m> as map-slice and adds it to gdb's global configurations.
for group, groupConfig := range m {
for g, groupConfig := range configMap {
cg := gdb.ConfigGroup{}
switch value := groupConfig.(type) {
case []interface{}:
@ -65,37 +65,51 @@ func Database(name ...string) gdb.DB {
}
}
if len(cg) > 0 {
intlog.Printf("%s, %#v", group, cg)
gdb.SetConfigGroup(group, cg)
if gdb.GetConfig(group) == nil {
intlog.Printf("add configuration for group: %s, %#v", g, cg)
gdb.SetConfigGroup(g, cg)
} else {
intlog.Printf("ignore configuration as it already exists for group: %s, %#v", g, cg)
intlog.Printf("%s, %#v", g, cg)
}
}
}
// Parse <m> as a single node configuration,
// which is the default group configuration.
if node := parseDBConfigNode(m); node != nil {
if node := parseDBConfigNode(configMap); node != nil {
cg := gdb.ConfigGroup{}
if node.LinkInfo != "" || node.Host != "" {
cg = append(cg, *node)
}
if len(cg) > 0 {
intlog.Printf("%s, %#v", gdb.DEFAULT_GROUP_NAME, cg)
gdb.SetConfigGroup(gdb.DEFAULT_GROUP_NAME, cg)
if gdb.GetConfig(group) == nil {
intlog.Printf("add configuration for group: %s, %#v", gdb.DEFAULT_GROUP_NAME, cg)
gdb.SetConfigGroup(gdb.DEFAULT_GROUP_NAME, cg)
} else {
intlog.Printf("ignore configuration as it already exists for group: %s, %#v", gdb.DEFAULT_GROUP_NAME, cg)
intlog.Printf("%s, %#v", gdb.DEFAULT_GROUP_NAME, cg)
}
}
}
// Create a new ORM object with given configurations.
if db, err := gdb.New(name...); err == nil {
// Initialize logger for ORM.
var m map[string]interface{}
m = Config().GetMap(fmt.Sprintf("%s.%s", nodeKey, gLOGGER_NODE_NAME))
if len(m) == 0 {
m = Config().GetMap(nodeKey)
}
if len(m) > 0 {
if err := db.GetLogger().SetConfigWithMap(m); err != nil {
panic(err)
if Config().Available() {
// Initialize logger for ORM.
var loggerConfigMap map[string]interface{}
loggerConfigMap = Config().GetMap(fmt.Sprintf("%s.%s", configNodeKey, gLOGGER_NODE_NAME))
if len(loggerConfigMap) == 0 {
loggerConfigMap = Config().GetMap(configNodeKey)
}
if len(loggerConfigMap) > 0 {
if err := db.GetLogger().SetConfigWithMap(loggerConfigMap); err != nil {
panic(err)
}
}
}
return db
} else {
// It panics often because it dose not find its configuration for given group.
panic(err)
}
return nil