add resource feature for gcfg

This commit is contained in:
John
2019-08-19 21:02:44 +08:00
parent e151055521
commit 10e03eef3b
28 changed files with 156 additions and 73 deletions

View File

@ -1,29 +1,4 @@
# 模板引擎目录
viewpath = "/home/www/templates/"
test = "v=1"
# MySQL数据库配置
[database]
[[database.default]]
host = "127.0.0.1"
port = "3306"
user = "root"
pass = ""
name = "test"
type = "mysql"
role = "master"
charset = "utf8"
priority = "1"
[[database.default]]
host = "127.0.0.1"
port = "3306"
user = "root"
pass = "8692651"
name = "test"
type = "mysql"
role = "master"
charset = "utf8"
priority = "1"
# Redis数据库配置
viewpath = "/home/www/templates"
[redis]
disk = "127.0.0.1:6379,0"
cache = "127.0.0.1:6379,1"

View File

@ -4,17 +4,17 @@ import (
"fmt"
"time"
"github.com/gogf/gf/os/gtimer"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gtime"
)
// 配置文件热更新示例
func main() {
c := g.Config()
// 每隔1秒打印当前配置项值用户可手动在外部修改文件内容gcfg读取到的配置项值会即时得到更新
gtime.SetInterval(time.Second, func() bool {
gtimer.SetInterval(time.Second, func() {
fmt.Println(c.Get("viewpath"))
return true
})
select {}

View File

@ -0,0 +1,21 @@
package main
import (
"github.com/gogf/gf/frame/g"
_ "github.com/gogf/gf/os/gres/testdata"
)
func main() {
g.Res().Dump()
g.Dump(g.Config().Get("redis"))
g.Config().SetFileName("my.ini")
g.Dump(g.Config().Get("redis"))
g.Config().SetPath("/config-custom")
g.Config().SetFileName("my.ini")
g.Dump(g.Config().Get("redis"))
g.Config().SetFileName("config.toml")
g.Dump(g.Config().Get("redis"))
}

View File

@ -12,7 +12,6 @@ func main() {
gres.Dump()
v := g.View()
v.SetResource(gres.Instance())
v.SetPath("/template/layout1")
s, err := v.Parse("layout.html")
fmt.Println(err)

View File

@ -14,6 +14,7 @@ import (
"github.com/gogf/gf/net/gtcp"
"github.com/gogf/gf/net/gudp"
"github.com/gogf/gf/os/gcfg"
"github.com/gogf/gf/os/gres"
"github.com/gogf/gf/os/gview"
)
@ -42,6 +43,18 @@ func Config(name ...string) *gcfg.Config {
return gins.Config(name...)
}
// Resource returns an instance of Resource.
// The parameter <name> is the name for the instance.
func Resource(name ...string) *gres.Resource {
return gins.Resource(name...)
}
// Res is alias of Resource.
// See Resource.
func Res(name ...string) *gres.Resource {
return Resource(name...)
}
// Database returns an instance of database ORM object with specified configuration group name.
func Database(name ...string) gdb.DB {
return gins.Database(name...)

View File

@ -17,6 +17,7 @@ import (
"github.com/gogf/gf/os/gcfg"
"github.com/gogf/gf/os/gfsnotify"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/os/gres"
"github.com/gogf/gf/os/gview"
"github.com/gogf/gf/text/gregex"
"github.com/gogf/gf/text/gstr"
@ -73,6 +74,12 @@ func Config(name ...string) *gcfg.Config {
return gcfg.Instance(name...)
}
// Resource returns an instance of Resource.
// The parameter <name> is the name for the instance.
func Resource(name ...string) *gres.Resource {
return gres.Instance(name...)
}
// 数据库操作对象,使用了连接池
func Database(name ...string) gdb.DB {
config := Config()

View File

@ -12,6 +12,8 @@ import (
"errors"
"fmt"
"github.com/gogf/gf/os/gres"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/container/gmap"
"github.com/gogf/gf/container/gtype"
@ -107,18 +109,28 @@ func (c *Config) filePath(file ...string) (path string) {
// The parameter <path> can be absolute or relative path,
// but absolute path is strongly recommended.
func (c *Config) SetPath(path string) error {
// Absolute path.
realPath := gfile.RealPath(path)
if realPath == "" {
// Relative path.
c.paths.RLockFunc(func(array []string) {
for _, v := range array {
if path, _ := gspath.Search(v, path); path != "" {
realPath = path
break
isDir := false
realPath := ""
if file := gres.Get(path); file != nil {
realPath = path
isDir = file.FileInfo().IsDir()
} else {
// Absolute path.
realPath = gfile.RealPath(path)
if realPath == "" {
// Relative path.
c.paths.RLockFunc(func(array []string) {
for _, v := range array {
if path, _ := gspath.Search(v, path); path != "" {
realPath = path
break
}
}
}
})
})
}
if realPath != "" {
isDir = gfile.IsDir(realPath)
}
}
// Path not exist.
if realPath == "" {
@ -140,7 +152,7 @@ func (c *Config) SetPath(path string) error {
return err
}
// Should be a directory.
if !gfile.IsDir(realPath) {
if !isDir {
err := fmt.Errorf(`[gcfg] SetPath failed: path "%s" should be directory type`, path)
if errorPrint() {
glog.Error(err)
@ -170,18 +182,28 @@ func (c *Config) SetViolenceCheck(check bool) {
// AddPath adds a absolute or relative path to the search paths.
func (c *Config) AddPath(path string) error {
// Absolute path.
realPath := gfile.RealPath(path)
if realPath == "" {
// Relative path.
c.paths.RLockFunc(func(array []string) {
for _, v := range array {
if path, _ := gspath.Search(v, path); path != "" {
realPath = path
break
isDir := false
realPath := ""
if file := gres.Get(path); file != nil {
realPath = path
isDir = file.FileInfo().IsDir()
} else {
// Absolute path.
realPath = gfile.RealPath(path)
if realPath == "" {
// Relative path.
c.paths.RLockFunc(func(array []string) {
for _, v := range array {
if path, _ := gspath.Search(v, path); path != "" {
realPath = path
break
}
}
}
})
})
}
if realPath != "" {
isDir = gfile.IsDir(realPath)
}
}
if realPath == "" {
buffer := bytes.NewBuffer(nil)
@ -201,7 +223,7 @@ func (c *Config) AddPath(path string) error {
}
return err
}
if !gfile.IsDir(realPath) {
if !isDir {
err := fmt.Errorf(`[gcfg] AddPath failed: path "%s" should be directory type`, path)
if errorPrint() {
glog.Error(err)
@ -233,15 +255,32 @@ func (c *Config) FilePath(file ...string) (path string) {
name = file[0]
}
c.paths.RLockFunc(func(array []string) {
for _, v := range array {
if path, _ = gspath.Search(v, name); path != "" {
break
for _, prefix := range array {
// Firstly checking the resource manager.
for _, v := range []string{"/", "/config", "/config/"} {
if file := gres.Get(prefix + v + name); file != nil {
path = file.Name()
return
}
}
if path, _ = gspath.Search(v+gfile.Separator+"config", name); path != "" {
break
// Secondly checking the file system.
if path, _ = gspath.Search(prefix, name); path != "" {
return
}
if path, _ = gspath.Search(prefix+gfile.Separator+"config", name); path != "" {
return
}
}
})
// Checking the configuration file in default paths.
if path == "" && !gres.IsEmpty() {
for _, v := range []string{"", "/", "/config", "/config/"} {
if file := gres.Get(v + name); file != nil {
path = file.Name()
return
}
}
}
return
}
@ -272,13 +311,17 @@ func (c *Config) getJson(file ...string) *gjson.Json {
if filePath == "" {
return nil
}
content = gfile.GetContents(filePath)
if file := gres.Get(filePath); file != nil {
content = string(file.Content())
} else {
content = gfile.GetContents(filePath)
}
}
if j, err := gjson.LoadContent(content, true); err == nil {
j.SetViolenceCheck(c.vc.Val())
// Add monitor for this configuration file,
// any changes of this file will refresh its cache in Config object.
if filePath != "" {
if !gres.Contains(filePath) {
_, err = gfsnotify.Add(filePath, func(event *gfsnotify.Event) {
c.jsons.Remove(name)
})

View File

@ -12,7 +12,7 @@ import (
const (
// Default group name for instance usage.
DEFAULT_GROUP_NAME = "default"
DEFAULT_NAME = "default"
)
var (
@ -23,7 +23,7 @@ var (
// Instance returns an instance of Config with default settings.
// The parameter <name> is the name for the instance.
func Instance(name ...string) *Config {
key := DEFAULT_GROUP_NAME
key := DEFAULT_NAME
if len(name) > 0 && name[0] != "" {
key = name[0]
}

View File

@ -62,6 +62,11 @@ func Contains(path string) bool {
return defaultResource.Contains(path)
}
// IsEmpty checks and returns whether the resource manager is empty.
func IsEmpty() bool {
return defaultResource.tree.IsEmpty()
}
// Scan returns the files under the given path, the parameter <path> should be a folder type.
//
// The pattern parameter <pattern> supports multiple file name patterns,

View File

@ -10,7 +10,7 @@ import "github.com/gogf/gf/container/gmap"
const (
// Default group name for instance usage.
DEFAULT_INSTANCE_NAME = "default"
DEFAULT_NAME = "default"
)
var (
@ -21,7 +21,7 @@ var (
// Instance returns an instance of Resource.
// The parameter <name> is the name for the instance.
func Instance(name ...string) *Resource {
key := DEFAULT_INSTANCE_NAME
key := DEFAULT_NAME
if len(name) > 0 && name[0] != "" {
key = name[0]
}

View File

@ -114,6 +114,11 @@ func (r *Resource) Contains(path string) bool {
return r.Get(path) != nil
}
// IsEmpty checks and returns whether the resource manager is empty.
func (r *Resource) IsEmpty() bool {
return r.tree.IsEmpty()
}
// Scan returns the files under the given path, the parameter <path> should be a folder type.
//
// The pattern parameter <pattern> supports multiple file name patterns,

View File

@ -0,0 +1,4 @@
viewpath = "/home/www/templates"
[redis]
disk = "127.0.0.1:6379,4"
cache = "127.0.0.1:6379,5"

View File

@ -0,0 +1,4 @@
viewpath = "/home/www/templates"
[redis]
disk = "127.0.0.1:6379,6"
cache = "127.0.0.1:6379,7"

View File

@ -0,0 +1,4 @@
viewpath = "/home/www/templates"
[redis]
disk = "127.0.0.1:6379,0"
cache = "127.0.0.1:6379,1"

4
os/gres/testdata/files/config/my.ini vendored Normal file
View File

@ -0,0 +1,4 @@
viewpath = "/home/www/templates"
[redis]
disk = "127.0.0.1:6379,2"
cache = "127.0.0.1:6379,3"

File diff suppressed because one or more lines are too long

View File

@ -177,7 +177,6 @@ func (view *View) SetPath(path string) error {
func (view *View) AddPath(path string) error {
isDir := false
realPath := ""
if file := gres.Get(path); file != nil {
realPath = path
isDir = file.FileInfo().IsDir()

View File

@ -46,7 +46,7 @@ var (
func (view *View) getTemplate(path string, pattern string) (tpl *template.Template, err error) {
r := templates.GetOrSetFuncLock(path, func() interface{} {
tpl = template.New(path).Delims(view.delimiters[0], view.delimiters[1]).Funcs(view.funcMap)
// Scan the resource object with more high priority.
// Firstly checking the resource manager.
if files := gres.Scan(path, pattern, true); len(files) > 0 {
var err error
for _, v := range files {
@ -60,7 +60,7 @@ func (view *View) getTemplate(path string, pattern string) (tpl *template.Templa
}
return tpl
}
// Secondly scan the file system.
// Secondly checking the file system.
files, err := gfile.ScanDir(path, pattern, true)
if err != nil {
return nil
@ -83,7 +83,7 @@ func (view *View) getTemplate(path string, pattern string) (tpl *template.Templa
// searchFile returns the found absolute path for <file>, and its template folder path.
func (view *View) searchFile(file string) (path string, folder string, err error) {
separator := gfile.Separator
// Scan the resource object with more high priority.
// Firstly checking the resource manager.
separator = "/"
view.paths.RLockFunc(func(array []string) {
f := (*gres.File)(nil)
@ -101,7 +101,7 @@ func (view *View) searchFile(file string) (path string, folder string, err error
}
}
})
// Secondly scan the file system.
// Secondly checking the file system.
if path == "" {
view.paths.RLockFunc(func(array []string) {
for _, v := range array {

View File

@ -10,7 +10,7 @@ import "github.com/gogf/gf/container/gmap"
const (
// Default group name for instance usage.
DEFAULT_INSTANCE_NAME = "default"
DEFAULT_NAME = "default"
)
var (
@ -21,7 +21,7 @@ var (
// Instance returns an instance of View with default settings.
// The parameter <name> is the name for the instance.
func Instance(name ...string) *View {
key := DEFAULT_INSTANCE_NAME
key := DEFAULT_NAME
if len(name) > 0 && name[0] != "" {
key = name[0]
}