From 45f165ea036b659d22628f7ec9bb697ec363bb89 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 14 Dec 2017 17:32:51 +0800 Subject: [PATCH] =?UTF-8?q?MVC=E7=BB=A7=E6=89=BF=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E8=B0=83=E6=95=B4=EF=BC=8C=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E3=80=81=E6=95=B0=E6=8D=AE=E5=BA=93=E7=AE=A1=E7=90=86=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E7=BB=84=E4=BB=B6=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.MD | 4 +- g/database/gdb/{db.go => gdb.go} | 130 +-------------- g/database/gdb/{db_base.go => gdb_base.go} | 0 g/database/gdb/gdb_config.go | 154 ++++++++++++++++++ .../gdb/{db_linkop.go => gdb_linkop.go} | 5 +- g/database/gdb/{db_mysql.go => gdb_mysql.go} | 0 g/database/gdb/{db_pgsql.go => gdb_pgsql.go} | 0 g/encoding/gjson/json.go | 14 ++ g/frame/gbase/gbase.go | 59 +++++++ g/frame/gconfig/gconfig.go | 124 +++++++++----- g/frame/ginstance/ginstance.go | 16 ++ g/frame/gmvc/controller.go | 3 + g/frame/gmvc/model.go | 8 +- g/frame/gmvc/view.go | 11 +- g/net/ghttp/http_client_request.go | 4 +- g/net/ghttp/http_server.go | 2 +- g/net/ghttp/http_server_response.go | 9 +- g/net/{gip/ip.go => gipv4/gipv4.go} | 10 +- g/net/gscanner/scanner.go | 6 +- geg/frame/config.json | 15 ++ geg/frame/mvc/controller/user/user.go | 6 +- geg/frame/mvc/main.go | 3 - geg/net/raft.go | 2 +- geg/other/test.go | 49 ++++-- 24 files changed, 423 insertions(+), 211 deletions(-) rename g/database/gdb/{db.go => gdb.go} (64%) rename g/database/gdb/{db_base.go => gdb_base.go} (100%) create mode 100644 g/database/gdb/gdb_config.go rename g/database/gdb/{db_linkop.go => gdb_linkop.go} (97%) rename g/database/gdb/{db_mysql.go => gdb_mysql.go} (100%) rename g/database/gdb/{db_pgsql.go => gdb_pgsql.go} (100%) create mode 100644 g/frame/gbase/gbase.go create mode 100644 g/frame/ginstance/ginstance.go rename g/net/{gip/ip.go => gipv4/gipv4.go} (94%) create mode 100644 geg/frame/config.json diff --git a/README.MD b/README.MD index 5b8924bc6..57eb5f70a 100644 --- a/README.MD +++ b/README.MD @@ -63,5 +63,5 @@ import "gitee.com/johng/gf/g/xxx" └── version.go 【版本信息】 ## 配置 - 键名 键值类型 配置说明 - Server名称.gf.mvc.view.path string 模板目录绝对路径 +1. 默认读取文件运行目录的config.json文件; +1. 支持多配置文件管理,默认配置文件目录为当前运行目录; diff --git a/g/database/gdb/db.go b/g/database/gdb/gdb.go similarity index 64% rename from g/database/gdb/db.go rename to g/database/gdb/gdb.go index 631f5f9ad..46072fd9d 100644 --- a/g/database/gdb/db.go +++ b/g/database/gdb/gdb.go @@ -3,7 +3,6 @@ package gdb import ( "fmt" - "sync" "errors" "database/sql" "gitee.com/johng/gf/g/os/glog" @@ -20,13 +19,6 @@ const ( OPTION_IGNORE = 3 ) -// 数据库配置包内对象 -var config struct { - sync.RWMutex - c Config // 数据库配置 - d string // 默认数据库分组名称 -} - // 数据库操作接口 type Link interface { Open (c *ConfigNode) (*sql.DB, error) @@ -83,120 +75,20 @@ type dbLink struct { charr string } -// 数据库配置 -type Config map[string]ConfigGroup - -// 数据库集群配置 -type ConfigGroup []ConfigNode - -// 数据库单项配置 -type ConfigNode struct { - Host string // 地址 - Port string // 端口 - User string // 账号 - Pass string // 密码 - Name string // 数据库名称 - Type string // 数据库类型:mysql, sqlite, mssql, pgsql, oracle(目前仅支持mysql) - Role string // (可选,默认为master)数据库的角色,用于主从操作分离,至少需要有一个master,参数值:master, slave - Charset string // (可选,默认为 utf-8)编码,默认为 utf-8 - Priority int // (可选)用于负载均衡的权重计算,当集群中只有一个节点时,权重没有任何意义 - Linkinfo string // (可选)自定义链接信息,当该字段被设置值时,以上链接字段(Host,Port,User,Pass,Name)将失效(该字段是一个扩展功能) -} - // 关联数组,绑定一条数据表记录 type Map map[string]interface{} // 关联数组列表(索引从0开始的数组),绑定多条记录 type List []Map -// 数据库集群配置示例,支持主从处理,多数据库集群支持 -/* -var DatabaseConfiguration = Config { - // 数据库集群配置名称 - "default" : ConfigGroup { - { - Host : "192.168.1.100", - Port : "3306", - User : "root", - Pass : "123456", - Name : "test", - Type : "mysql", - Role : "master", - Charset : "utf-8", - Priority : 100, - }, - { - Host : "192.168.1.101", - Port : "3306", - User : "root", - Pass : "123456", - Name : "test", - Type : "mysql", - Role : "slave", - Charset : "utf-8", - Priority : 100, - }, - }, -} -*/ - -// 包初始化 -func init() { - config.c = make(Config) - config.d = "default" +// 获得默认的数据库操作对象单例 +func Instance () (Link, error) { + return instance(config.d) } -// 设置当前应用的数据库配置信息,进行全局数据库配置覆盖操作 -// 支持三种数据类型的输入参数:Config, ConfigGroup, ConfigNode -func SetConfig (c interface{}) error { - config.Lock() - defer config.Unlock() - - switch c.(type) { - case Config: - config.c = c.(Config) - - case ConfigGroup: - config.c = Config {"default" : c.(ConfigGroup)} - - case ConfigNode: - config.c = Config {"default" : ConfigGroup { c.(ConfigNode) }} - - default: - return errors.New("invalid config type, types should be in: Config, ConfigGroup, ConfigNode") - } - return nil -} - -// 添加一台数据库服务器配置 -func AddConfigNode (group string, node ConfigNode) { - config.Lock() - config.c[group] = append(config.c[group], node) - config.Unlock() -} - -// 添加数据库服务器集群配置 -func AddConfigGroup (group string, nodes ConfigGroup) { - config.Lock() - config.c[group] = nodes - config.Unlock() -} - -// 添加默认链接的一台数据库服务器配置 -func AddDefaultConfigNode (node ConfigNode) { - AddConfigNode("default", node) -} - -// 添加默认链接的数据库服务器集群配置 -func AddDefaultConfigGroup (nodes ConfigGroup) { - AddConfigGroup("default", nodes) -} - -// 设置默认链接的数据库链接配置项(默认是 default) -func SetDefaultGroup (groupName string) { - config.Lock() - config.d = groupName - config.Unlock() +// 获得指定配置项的数据库草最对象单例 +func InstanceByGroup(groupName string) (Link, error) { + return instance(groupName) } // 根据配置项获取一个数据库操作对象单例 @@ -216,16 +108,6 @@ func instance (groupName string) (Link, error) { } } -// 获得默认的数据库操作对象单例 -func Instance () (Link, error) { - return instance(config.d) -} - -// 获得指定配置项的数据库草最对象单例 -func InstanceByGroup(groupName string) (Link, error) { - return instance(groupName) -} - // 使用默认选项进行连接,数据库集群配置项:default func New() (Link, error) { return NewByGroup(config.d) diff --git a/g/database/gdb/db_base.go b/g/database/gdb/gdb_base.go similarity index 100% rename from g/database/gdb/db_base.go rename to g/database/gdb/gdb_base.go diff --git a/g/database/gdb/gdb_config.go b/g/database/gdb/gdb_config.go new file mode 100644 index 000000000..31b03490b --- /dev/null +++ b/g/database/gdb/gdb_config.go @@ -0,0 +1,154 @@ +// 对常用关系数据库的封装管理包 +package gdb + +import ( + "sync" + "regexp" + "strings" + "strconv" +) + +const ( + gDEFAULT_CONFIG_GROUP_NAME = "default" // 默认配置名称 +) + +// 数据库配置包内对象 +var config struct { + sync.RWMutex + c Config // 数据库配置 + d string // 默认数据库分组名称 +} + +// 数据库配置 +type Config map[string]ConfigGroup + +// 数据库集群配置 +type ConfigGroup []ConfigNode + +// 数据库单项配置 +type ConfigNode struct { + Host string // 地址 + Port string // 端口 + User string // 账号 + Pass string // 密码 + Name string // 数据库名称 + Type string // 数据库类型:mysql, sqlite, mssql, pgsql, oracle(目前仅支持mysql) + Role string // (可选,默认为master)数据库的角色,用于主从操作分离,至少需要有一个master,参数值:master, slave + Charset string // (可选,默认为 utf-8)编码,默认为 utf-8 + Priority int // (可选)用于负载均衡的权重计算,当集群中只有一个节点时,权重没有任何意义 + Linkinfo string // (可选)自定义链接信息,当该字段被设置值时,以上链接字段(Host,Port,User,Pass,Name)将失效(该字段是一个扩展功能) +} + +// 数据库集群配置示例,支持主从处理,多数据库集群支持 +/* +var DatabaseConfiguration = Config { + // 数据库集群配置名称 + "default" : ConfigGroup { + { + Host : "192.168.1.100", + Port : "3306", + User : "root", + Pass : "123456", + Name : "test", + Type : "mysql", + Role : "master", + Charset : "utf-8", + Priority : 100, + }, + { + Host : "192.168.1.101", + Port : "3306", + User : "root", + Pass : "123456", + Name : "test", + Type : "mysql", + Role : "slave", + Charset : "utf-8", + Priority : 100, + }, + }, +} +*/ + +// 包初始化 +func init() { + config.c = make(Config) + config.d = gDEFAULT_CONFIG_GROUP_NAME +} + +// 设置当前应用的数据库配置信息,进行全局数据库配置覆盖操作 +func SetConfig (c Config) { + config.Lock() + defer config.Unlock() + config.c = c +} + +// 添加数据库服务器集群配置 +func AddConfigGroup (group string, nodes ConfigGroup) { + config.Lock() + config.c[group] = nodes + config.Unlock() +} + +// 添加一台数据库服务器配置 +func AddConfigNode (group string, node ConfigNode) { + config.Lock() + config.c[group] = append(config.c[group], node) + config.Unlock() +} + +// 添加一台数据库服务器配置,通过解析规范的字符串配置实现 +// 配置格式:账号@地址:端口,密码,数据库名称,数据库类型[,集群角色(master|slave),字符编码,负载均衡优先级,自定义链接] +func AddConfigNodeByString (group string, nodestr string) { + reg, _ := regexp.Compile(`(.+)@(.+):([^,]+),([^,]+),([^,]+),([^,]+)`) + match := reg.FindStringSubmatch(nodestr) + if match != nil { + node := ConfigNode{ + User : strings.TrimSpace(match[1]), + Host : strings.TrimSpace(match[2]), + Port : strings.TrimSpace(match[3]), + Pass : strings.TrimSpace(match[4]), + Name : strings.TrimSpace(match[5]), + Type : strings.TrimSpace(match[6]), + } + if len(match[0]) + 1 < len(nodestr) { + extra := strings.Split(nodestr[len(match[0]) + 1:], ",") + if len(extra) > 0 { + node.Role = strings.TrimSpace(extra[0]) + } + if len(extra) > 1 { + node.Charset = strings.TrimSpace(extra[1]) + } + if len(extra) > 2 { + node.Priority, _ = strconv.Atoi(strings.TrimSpace(extra[2])) + } + if len(extra) > 3 { + index := len(extra[0]) + len(extra[1]) + len(extra[2]) + 3 + node.Linkinfo = strings.TrimSpace(nodestr[len(match[0]) + 1 + index:]) + } + } + AddConfigNode(group, node) + } +} + +// 添加默认链接的一台数据库服务器配置,通过解析规范的字符串配置实现 +func AddDefaultConfigNodeByString (nodestr string) { + AddConfigNodeByString(gDEFAULT_CONFIG_GROUP_NAME, nodestr) +} + +// 添加默认链接的一台数据库服务器配置 +func AddDefaultConfigNode (node ConfigNode) { + AddConfigNode(gDEFAULT_CONFIG_GROUP_NAME, node) +} + +// 添加默认链接的数据库服务器集群配置 +func AddDefaultConfigGroup (nodes ConfigGroup) { + AddConfigGroup(gDEFAULT_CONFIG_GROUP_NAME, nodes) +} + +// 设置默认链接的数据库链接配置项(默认是 default) +func SetDefaultGroup (groupName string) { + config.Lock() + config.d = groupName + config.Unlock() +} diff --git a/g/database/gdb/db_linkop.go b/g/database/gdb/gdb_linkop.go similarity index 97% rename from g/database/gdb/db_linkop.go rename to g/database/gdb/gdb_linkop.go index 1f99765ea..8d4cdee14 100644 --- a/g/database/gdb/db_linkop.go +++ b/g/database/gdb/gdb_linkop.go @@ -2,14 +2,11 @@ package gdb import ( "fmt" - "database/sql" "errors" + "database/sql" _ "github.com/go-sql-driver/mysql" ) -// gf的数据库操作支持普通方法操作及链式操作两种方式,本文件是链式操作的封装,提供非常简便的CURD方法 - - // 数据库链式操作对象 type gLinkOp struct { link Link diff --git a/g/database/gdb/db_mysql.go b/g/database/gdb/gdb_mysql.go similarity index 100% rename from g/database/gdb/db_mysql.go rename to g/database/gdb/gdb_mysql.go diff --git a/g/database/gdb/db_pgsql.go b/g/database/gdb/gdb_pgsql.go similarity index 100% rename from g/database/gdb/db_pgsql.go rename to g/database/gdb/gdb_pgsql.go diff --git a/g/encoding/gjson/json.go b/g/encoding/gjson/json.go index 9f1689c56..9ef2c0090 100644 --- a/g/encoding/gjson/json.go +++ b/g/encoding/gjson/json.go @@ -6,6 +6,7 @@ import ( "strings" "strconv" "fmt" + "io/ioutil" ) // json解析结果存放数组 @@ -56,6 +57,19 @@ func DecodeToJson (s string) (*Json, error) { return &Json{ &result }, nil } +// 加载json文件内容,并转换为json对象 +func Load (path string) (*Json, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + var result interface{} + if err := json.Unmarshal(data, &result); err != nil { + return nil, err + } + return &Json{ &result }, nil +} + // 将变量转换为Json对象进行处理,该变量至少应当是一个map或者array,否者转换没有意义 func NewJson(v *interface{}) *Json { return &Json{ v } diff --git a/g/frame/gbase/gbase.go b/g/frame/gbase/gbase.go new file mode 100644 index 000000000..ee2fc723e --- /dev/null +++ b/g/frame/gbase/gbase.go @@ -0,0 +1,59 @@ +// 基类 +package gbase + +import ( + "gitee.com/johng/gf/g/os/gfile" + "gitee.com/johng/gf/g/database/gdb" + "gitee.com/johng/gf/g/frame/gconfig" + "gitee.com/johng/gf/g/frame/ginstance" +) + +const ( + gDEFAULT_CONFIG_FILE = "config.json" // 默认读取的配置文件名称 +) + +// 框架基类 +type Base struct { + Db gdb.Link + Config *gconfig.Config +} + +// 基类初始化,如若需要自定义初始化内置核心对象组件,可在继承子类中覆盖此方法 +func (b *Base) Init() { + // 默认配置目录为当前程序运行目录 + if b.Config == nil { + path := gfile.SelfDir() + ckey := "gf_config_with_path_" + path + result := ginstance.Get(ckey) + if result != nil { + b.Config = result.(*gconfig.Config) + } else { + b.Config = gconfig.New(path) + b.Config.Add(gDEFAULT_CONFIG_FILE) + ginstance.Set(ckey, b.Config) + } + } + // 数据库操作对象初始化 + // 全局只有一个数据库单例对象,可以配置不同分组的配置进行使用 + if b.Db == nil { + ckey := "gf_database" + result := ginstance.Get(ckey) + if result != nil { + b.Db = result.(gdb.Link) + } else { + if m := b.Config.GetMap("database"); m != nil { + for group, v := range m { + if list, ok := v.([]interface{}); ok { + for _, nodei := range list { + gdb.AddConfigNodeByString(group, nodei.(string)) + } + } + } + } + if link, err := gdb.Instance(); err != nil { + b.Db = link + ginstance.Set(ckey, b.Db) + } + } + } +} \ No newline at end of file diff --git a/g/frame/gconfig/gconfig.go b/g/frame/gconfig/gconfig.go index be838d0c1..48a55eee8 100644 --- a/g/frame/gconfig/gconfig.go +++ b/g/frame/gconfig/gconfig.go @@ -2,63 +2,105 @@ package gconfig import ( + "gitee.com/johng/gf/g/os/gfile" "gitee.com/johng/gf/g/container/gmap" "gitee.com/johng/gf/g/encoding/gjson" - "gitee.com/johng/gf/g/os/gfile" - "errors" ) -// 配置对象 -var config = gmap.NewStringInterfaceMap() +const ( + gDEFAULT_CONFIG_NAME = "config" // 默认的配置管理文件名称 +) -// 获取配置 -func Get(k string) interface{} { - return config.Get(k) +// 配置管理对象 +type Config struct { + path string // 配置文件存放目录,绝对路径 + jsons *gmap.StringInterfaceMap // 配置文件对象 } -func GetInt(k string) int { - if v := config.Get(k); v != nil { - if r, ok := v.(int); ok { - return r - } +// 生成一个配置管理对象 +func New(path string) *Config { + return &Config{ + path : path, + jsons : gmap.NewStringInterfaceMap(), } - return 0 } -func GetString(k string) string { - if v := config.Get(k); v != nil { - if r, ok := v.(string); ok { - return r - } +// 判断从哪个配置文件中获取内容 +func (c *Config) name(names []string) string { + name := gDEFAULT_CONFIG_NAME + if len(names) > 0 { + name = names[0] + } + return name +} + +// 添加配置文件到配置管理器中,第二个参数为非必须,如果不输入表示添加进入默认的配置名称中 +func (c *Config) Add(file string, names...string) error { + path := c.path + gfile.Separator + file + if j, err := gjson.Load(path); err == nil { + c.jsons.Set(c.name(names), j) + return nil + } else { + return err + } +} + +// 获取配置项,当不存在时返回nil +func (c *Config) Get(pattern string, names...string) interface{} { + if r := c.jsons.Get(c.name(names)); r != nil { + return r.(*gjson.Json).Get(pattern) + } + return nil +} + +// 获得一个键值对关联数组/哈希表,方便操作,不需要自己做类型转换 +// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil +func (c *Config) GetMap(pattern string, names...string) map[string]interface{} { + if r := c.jsons.Get(c.name(names)); r != nil { + return r.(*gjson.Json).GetMap(pattern) + } + return nil +} + +// 获得一个数组[]interface{},方便操作,不需要自己做类型转换 +// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil +func (c *Config) GetArray(pattern string, names...string) []interface{} { + if r := c.jsons.Get(c.name(names)); r != nil { + return r.(*gjson.Json).GetArray(pattern) + } + return nil +} + +// 返回指定json中的string +func (c *Config) GetString(pattern string, names...string) string { + if r := c.jsons.Get(c.name(names)); r != nil { + return r.(*gjson.Json).GetString(pattern) } return "" } -// 适用于json文件配置,在设置的时候通过gjson进行解析后再保存 -func GetJson(k string) *gjson.Json { - if v := config.Get(k); v != nil { - if r, ok := v.(*gjson.Json); ok { - return r - } +// 返回指定json中的bool +func (c *Config) GetBool(pattern string, names...string) bool { + if r := c.jsons.Get(c.name(names)); r != nil { + return r.(*gjson.Json).GetBool(pattern) } - return nil + return false } -// 设置配置 -func Set(k string, v interface{}) { - config.Set(k, v) +// 返回指定json中的float64 +func (c *Config) GetFloat64(pattern string, names...string) float64 { + if r := c.jsons.Get(c.name(names)); r != nil { + return r.(*gjson.Json).GetFloat64(pattern) + } + return 0 } -// 加载json文件配置 -func Load(key string, path string) error { - content := gfile.GetContents(path) - if len(content) == 0 { - return errors.New("load json file failed, path: " + path) - } - if json, err := gjson.DecodeToJson(content); err == nil { - config.Set(key, json) - } else { - return err - } - return nil -} \ No newline at end of file +// 返回指定json中的float64->int +func (c *Config) GetInt(pattern string, names...string) int { + return int(c.GetFloat64(pattern)) +} + +// 返回指定json中的float64->int64 +func (c *Config) GetInt64(pattern string, names...string) int64 { + return int64(c.GetFloat64(pattern)) +} diff --git a/g/frame/ginstance/ginstance.go b/g/frame/ginstance/ginstance.go new file mode 100644 index 000000000..35e7b228c --- /dev/null +++ b/g/frame/ginstance/ginstance.go @@ -0,0 +1,16 @@ +package ginstance + +import "gitee.com/johng/gf/g/container/gmap" + +// 单例对象存储器 +var instances = gmap.NewStringInterfaceMap() + +// 获取单例对象 +func Get(k string) interface{} { + return instances.Get(k) +} + +// 设置单例对象 +func Set(k string, v interface{}) { + instances.Set(k, v) +} \ No newline at end of file diff --git a/g/frame/gmvc/controller.go b/g/frame/gmvc/controller.go index d12883b50..c93334d66 100644 --- a/g/frame/gmvc/controller.go +++ b/g/frame/gmvc/controller.go @@ -3,6 +3,7 @@ package gmvc import ( "gitee.com/johng/gf/g/net/ghttp" + "gitee.com/johng/gf/g/frame/gbase" "gitee.com/johng/gf/g/net/gsession" ) @@ -12,6 +13,7 @@ const ( // 控制器基类 type Controller struct { + gbase.Base Server *ghttp.Server // Web Server对象 Request *ghttp.ClientRequest // 请求数据对象 Response *ghttp.ServerResponse // 返回数据对象 @@ -22,6 +24,7 @@ type Controller struct { // 控制器初始化 func (c *Controller) Init(s *ghttp.Server, r *ghttp.ClientRequest, w *ghttp.ServerResponse) { + c.Base.Init() c.Server = s c.Request = r c.Response = w diff --git a/g/frame/gmvc/model.go b/g/frame/gmvc/model.go index 44971bf92..a378bd06b 100644 --- a/g/frame/gmvc/model.go +++ b/g/frame/gmvc/model.go @@ -1,2 +1,8 @@ -// 好像没什么好封装的 +// 模型基类 package gmvc + +import "gitee.com/johng/gf/g/frame/gbase" + +type Model struct { + gbase.Base +} \ No newline at end of file diff --git a/g/frame/gmvc/view.go b/g/frame/gmvc/view.go index 2f9ceb910..92aebdb88 100644 --- a/g/frame/gmvc/view.go +++ b/g/frame/gmvc/view.go @@ -4,11 +4,13 @@ import ( "sync" "html/template" "gitee.com/johng/gf/g/os/gview" - "gitee.com/johng/gf/g/frame/gconfig" + "gitee.com/johng/gf/g/frame/gbase" + "gitee.com/johng/gf/g/os/gfile" ) // 视图对象(一个请求一个视图对象,用完即销毁) type View struct { + gbase.Base mu sync.RWMutex // 并发互斥锁 ctl *Controller // 所属控制器 view *gview.View // 底层视图对象 @@ -17,10 +19,13 @@ type View struct { // 创建一个MVC请求中使用的视图对象 func NewView(c *Controller) *View { - path := c.Server.GetName() + ".gf.mvc.view.path" + viewpath := gfile.SelfDir() + if r := c.Config.Get("viewpath"); r != nil { + viewpath = r.(string) + } return &View{ ctl : c, - view : gview.GetView(gconfig.GetString(path)), + view : gview.GetView(viewpath), data : make(map[string]interface{}), } } diff --git a/g/net/ghttp/http_client_request.go b/g/net/ghttp/http_client_request.go index 0b053269e..f79a96e25 100644 --- a/g/net/ghttp/http_client_request.go +++ b/g/net/ghttp/http_client_request.go @@ -174,7 +174,9 @@ func (r *ClientRequest) GetRaw() string { func (r *ClientRequest) GetJson() *gjson.Json { data := r.GetRaw() if data != "" { - return gjson.DecodeToJson(data) + if j, err := gjson.DecodeToJson(data); err == nil { + return j + } } return nil } diff --git a/g/net/ghttp/http_server.go b/g/net/ghttp/http_server.go index 52a861728..06b6528fe 100644 --- a/g/net/ghttp/http_server.go +++ b/g/net/ghttp/http_server.go @@ -32,7 +32,7 @@ type Server struct { // 域名、URI与回调函数的绑定记录表 type HandlerMap map[string]HandlerFunc -// http回调函数信息 +// http回调函数注册信息 type HandlerFunc struct { ctype reflect.Type // 控制器类型 fname string // 回调方法名称 diff --git a/g/net/ghttp/http_server_response.go b/g/net/ghttp/http_server_response.go index fd6f9a7cd..b8e451950 100644 --- a/g/net/ghttp/http_server_response.go +++ b/g/net/ghttp/http_server_response.go @@ -35,11 +35,16 @@ func (r *ServerResponse) WriteString(content string) { } // 返回固定格式的json -func (r *ServerResponse) WriteJson(result int, message string, data interface{}) { +func (r *ServerResponse) WriteJson(result int, message string, data interface{}) error { r.Header().Set("Content-Type", "application/json") r.bufmu.Lock() defer r.bufmu.Unlock() - r.buffer = append(r.buffer, gjson.Encode(ResponseJson{ result, message, data })...) + if jsonstr, err := gjson.Encode(ResponseJson{ result, message, data }); err != nil { + return err + } else { + r.buffer = append(r.buffer, jsonstr...) + } + return nil } // 返回内容编码 diff --git a/g/net/gip/ip.go b/g/net/gipv4/gipv4.go similarity index 94% rename from g/net/gip/ip.go rename to g/net/gipv4/gipv4.go index ac90a8b61..621ee9420 100644 --- a/g/net/gip/ip.go +++ b/g/net/gipv4/gipv4.go @@ -1,4 +1,4 @@ -package gip +package gipv4 import ( "net" @@ -10,12 +10,8 @@ import ( // ip字符串转为整形 func Ip2long(ipstr string) (ip uint32) { - r := `^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$` - reg, err := regexp.Compile(r) - if err != nil { - return - } - ips := reg.FindStringSubmatch(ipstr) + reg, _ := regexp.Compile(`^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$`) + ips := reg.FindStringSubmatch(ipstr) if ips == nil { return } diff --git a/g/net/gscanner/scanner.go b/g/net/gscanner/scanner.go index 3f66c9b9b..acd63a908 100644 --- a/g/net/gscanner/scanner.go +++ b/g/net/gscanner/scanner.go @@ -34,8 +34,8 @@ func (s *scanner) ScanIp(startIp string, endIp string, port int, callback func(n return errors.New("callback function should not be nil") } var waitGroup sync.WaitGroup - startIplong := gip.Ip2long(startIp) - endIplong := gip.Ip2long(endIp) + startIplong := gipv4.Ip2long(startIp) + endIplong := gipv4.Ip2long(endIp) result := endIplong - startIplong if startIplong == 0 || endIplong == 0 { return errors.New("invalid startip or endip: ipv4 string should be given") @@ -56,7 +56,7 @@ func (s *scanner) ScanIp(startIp string, endIp string, port int, callback func(n } //fmt.Println("scanning:", ip, "done") waitGroup.Done() - }(gip.Long2ip(i)) + }(gipv4.Long2ip(i)) } waitGroup.Wait() return nil diff --git a/geg/frame/config.json b/geg/frame/config.json new file mode 100644 index 000000000..9dbfbc96c --- /dev/null +++ b/geg/frame/config.json @@ -0,0 +1,15 @@ +{ + "viewpath" : "/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/mvc/view", + "database" : { + "default" : [ + "root@127.0.0.1:3306,123456,test,mysql", + "root@127.0.0.1:3306,123456,test,mysql", + "root@127.0.0.1:3306,123456,test,mysql" + ], + "user-center" : [ + "root@127.0.0.1:3306,123456,ucenter,mysql", + "root@127.0.0.1:3306,123456,ucenter,mysql", + "root@127.0.0.1:3306,123456,ucenter,mysql" + ] + } +} \ No newline at end of file diff --git a/geg/frame/mvc/controller/user/user.go b/geg/frame/mvc/controller/user/user.go index 235eec881..b859b4ea8 100644 --- a/geg/frame/mvc/controller/user/user.go +++ b/geg/frame/mvc/controller/user/user.go @@ -23,11 +23,9 @@ func init() { // 定义操作逻辑 func (c *ControllerUser) Info() { - //c.Response.WriteString("user information page") + fmt.Println(c.Db) c.View.Assign("name", "john") - if err := c.View.Display("user/index"); err != nil { - fmt.Println(err) - } + c.View.Display("user/index") } diff --git a/geg/frame/mvc/main.go b/geg/frame/mvc/main.go index 8a29f210b..7b5205fe6 100644 --- a/geg/frame/mvc/main.go +++ b/geg/frame/mvc/main.go @@ -3,12 +3,9 @@ package main import ( "gitee.com/johng/gf/g/net/ghttp" _ "gitee.com/johng/gf/geg/frame/mvc/controller/user" - - "gitee.com/johng/gf/g/frame/gconfig" ) func main() { - gconfig.Set("johng.gf.mvc.view.path", "/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/mvc/view") ghttp.GetServer("johng").SetAddr(":8199") ghttp.GetServer("johng").Run() } diff --git a/geg/net/raft.go b/geg/net/raft.go index a8e533f7b..ff4a9c26d 100644 --- a/geg/net/raft.go +++ b/geg/net/raft.go @@ -9,7 +9,7 @@ import ( func main() { - ips, err := gip.IntranetIP() + ips, err := gipv4.IntranetIP() if err != nil { log.Println(err) return diff --git a/geg/other/test.go b/geg/other/test.go index a0443b4b9..6a4c48873 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,23 +1,44 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/os/gview" + "regexp" + "strings" + "strconv" + "gitee.com/johng/gf/g/database/gdb" ) -type B struct { - +func Add(path string, name ... string) { + fmt.Println(name) } -func add() int {return 1} - func main() { - view := gview.New("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/mvc/view/user/") - tpl, _ := view.Template("info") - tpl.BindFunc("include", add) - fmt.Println(tpl.Parse(nil)) - //t, err := template.New("text").Funcs(template.FuncMap{"add":add}).Parse(`{{add 1 2}}`) - //if err != nil { - // panic(err) - //} - //t.Execute(os.Stdout, u) + nodestr := "账号@地址:端口 ,密码 , 数据库名称, 数据库类型, 集群角色 , 字符编码, 负载均衡优先级 , 12345" + reg, _ := regexp.Compile(`(.+)@(.+):([^,]+),([^,]+),([^,]+),([^,]+)`) + match := reg.FindStringSubmatch(nodestr) + if match != nil { + node := gdb.ConfigNode{ + User : strings.TrimSpace(match[1]), + Host : strings.TrimSpace(match[2]), + Port : strings.TrimSpace(match[3]), + Pass : strings.TrimSpace(match[4]), + Name : strings.TrimSpace(match[5]), + Type : strings.TrimSpace(match[6]), + } + extra := strings.Split(nodestr[len(match[0]) + 1:], ",") + if len(extra) > 0 { + node.Role = strings.TrimSpace(extra[0]) + } + if len(extra) > 1 { + node.Charset = strings.TrimSpace(extra[1]) + } + if len(extra) > 2 { + node.Priority, _ = strconv.Atoi(strings.TrimSpace(extra[2])) + } + if len(extra) > 3 { + index := len(extra[0]) + len(extra[1]) + len(extra[2]) + 3 + node.Linkinfo = strings.TrimSpace(nodestr[len(match[0]) + 1 + index:]) + } + fmt.Println(node) + } + } \ No newline at end of file