From 9af4f959829b703428c4b87c039b117fe649b92e Mon Sep 17 00:00:00 2001 From: john Date: Wed, 27 Jun 2018 20:58:28 +0800 Subject: [PATCH 01/18] =?UTF-8?q?=E4=BF=AE=E6=AD=A3gconv=E5=8C=85float32->?= =?UTF-8?q?float64=E7=B2=BE=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/util/gconv/gconv.go | 4 ++-- geg/net/ghttp/server/performance/client.go | 4 ++-- geg/other/test.go | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index f8923b214..1b3f6903d 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -106,7 +106,7 @@ func String(i interface{}) string { case uint16: return strconv.FormatUint(uint64(value), 10) case uint32: return strconv.FormatUint(uint64(value), 10) case uint64: return strconv.FormatUint(uint64(value), 10) - case float32: return strconv.FormatFloat(float64(value), 'f', -1, 64) + case float32: return strconv.FormatFloat(float64(value), 'f', -1, 32) case float64: return strconv.FormatFloat(value, 'f', -1, 64) case bool: return strconv.FormatBool(value) case string: return value @@ -289,7 +289,7 @@ func Float32 (i interface{}) float32 { if v, ok := i.(float32); ok { return v } - v, _ := strconv.ParseFloat(String(i), 32) + v, _ := strconv.ParseFloat(String(i), 64) return float32(v) } diff --git a/geg/net/ghttp/server/performance/client.go b/geg/net/ghttp/server/performance/client.go index e83c1a63a..4955f222a 100644 --- a/geg/net/ghttp/server/performance/client.go +++ b/geg/net/ghttp/server/performance/client.go @@ -9,7 +9,7 @@ import ( ) func main() { - clientMax := 10 + clientMax := 1000 requestMax := 1000 failureNum := gtype.NewInt64() successNum := gtype.NewInt64() @@ -21,7 +21,7 @@ func main() { go func(clientId int) { url := "http://127.0.0.1:8199/" for i := 0; i < requestMax; i++ { - url = fmt.Sprintf("http://127.0.0.1:8199/%d_%d", clientId, i) + //url = fmt.Sprintf("http://127.0.0.1:8199/%d_%d", clientId, i) if c, e := ghttp.Get(url); e == nil { c.Close() successNum.Add(1) diff --git a/geg/other/test.go b/geg/other/test.go index cd8681879..7b38824b0 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,11 +1,12 @@ package main import ( - "time" "fmt" + "gitee.com/johng/gf/g/util/gconv" ) func main() { - t := time.Now().Zone() - fmt.Println(z) + fmt.Println(gconv.Float64(float32(19.66))) + fmt.Println(float64(float32(19.66))) + } \ No newline at end of file From 3a69773972f13d46a5c6051f4c5e997cec111d88 Mon Sep 17 00:00:00 2001 From: john Date: Wed, 27 Jun 2018 21:03:08 +0800 Subject: [PATCH 02/18] TODO++ --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 01fba4741..64173de24 100644 --- a/TODO +++ b/TODO @@ -8,6 +8,7 @@ orm增加更多数据库支持; 增加可选择性的orm tag特性,用以数据表记录与struct对象转换的键名属性映射; ghttp.Response增加输出内容后自动退出当前请求机制,不需要用户手动return,参考beego如何实现; Cookie&Session数据池化处理; +ghttp.Client增加proxy特性; DONE: 1. gconv完善针对不同类型的判断,例如:尽量减少sprintf("%v", xxx)来执行string类型的转换; From 412ea3f85099daf56c4647a6a37169e7c72c6cd2 Mon Sep 17 00:00:00 2001 From: GarfieldKwong Date: Thu, 28 Jun 2018 19:41:59 +0800 Subject: [PATCH 03/18] =?UTF-8?q?=E4=BF=AE=E6=AD=A3garray=E7=9A=84?= =?UTF-8?q?=E6=BD=9C=E5=9C=A8=E9=97=AE=E9=A2=98=E3=80=82=E5=BD=93=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E4=B8=AD=E6=9C=89=E4=BB=BB=E4=BD=95=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=8F=91=E7=94=9F=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E4=BA=92?= =?UTF-8?q?=E6=96=A5=E9=94=81=E5=B0=86=E4=B8=8D=E4=BC=9A=E8=A2=AB=E9=87=8A?= =?UTF-8?q?=E6=94=BE=E3=80=82=20=E4=BA=92=E6=96=A5=E6=89=80=E9=87=8A?= =?UTF-8?q?=E6=94=BE=E8=A6=81=E7=94=A8defer=E6=9D=A5=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/garray/garray_int.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/g/container/garray/garray_int.go b/g/container/garray/garray_int.go index ebaca9a5e..ba0650506 100644 --- a/g/container/garray/garray_int.go +++ b/g/container/garray/garray_int.go @@ -40,39 +40,40 @@ func NewIntArray(size int, cap ... int) *IntArray { // 获取指定索引的数据项, 调用方注意判断数组边界 func (a *IntArray) Get(index int) int { a.mu.RLock() + defer a.mu.RUnlock() value := a.array[index] - a.mu.RUnlock() return value } // 设置指定索引的数据项, 调用方注意判断数组边界 func (a *IntArray) Set(index int, value int) { a.mu.Lock() + defer a.mu.RUnlock() a.array[index] = value - a.mu.Unlock() } // 在当前索引位置前插入一个数据项, 调用方注意判断数组边界 func (a *IntArray) Insert(index int, value int) { a.mu.Lock() + defer a.mu.RUnlock() rear := append([]int{}, a.array[index : ]...) a.array = append(a.array[0 : index], value) a.array = append(a.array, rear...) - a.mu.Unlock() + } // 删除指定索引的数据项, 调用方注意判断数组边界 func (a *IntArray) Remove(index int) { a.mu.Lock() + defer a.mu.RUnlock() a.array = append(a.array[ : index], a.array[index + 1 : ]...) - a.mu.Unlock() } // 追加数据项 func (a *IntArray) Append(value int) { a.mu.Lock() + defer a.mu.RUnlock() a.array = append(a.array, value) - a.mu.Unlock() } // 数组长度 @@ -94,12 +95,12 @@ func (a *IntArray) Slice() []int { // 清空数据数组 func (a *IntArray) Clear() { a.mu.Lock() + defer a.mu.RUnlock() if a.cap > 0 { a.array = make([]int, a.size, a.cap) } else { a.array = make([]int, a.size) } - a.mu.Unlock() } // 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1 @@ -140,13 +141,13 @@ func (a *IntArray) Search(value int) int { // 使用自定义方法执行加锁修改操作 func (a *IntArray) LockFunc(f func(array []int)) { a.mu.Lock() + defer a.mu.Unlock() f(a.array) - a.mu.Unlock() } // 使用自定义方法执行加锁读取操作 func (a *IntArray) RLockFunc(f func(array []int)) { a.mu.RLock() + defer a.mu.Unlock() f(a.array) - a.mu.RUnlock() -} +} \ No newline at end of file From 4df02e279191aadf2c21ba5b9ad75346ebe7a3ac Mon Sep 17 00:00:00 2001 From: john Date: Fri, 29 Jun 2018 13:03:29 +0800 Subject: [PATCH 04/18] =?UTF-8?q?gproc=E5=A4=9A=E8=BF=9B=E7=A8=8B=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=8A=9F=E8=83=BD=E5=A2=9E=E5=8A=A0CommEnabled?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO | 4 +++ g/os/gcmd/gcmd.go | 2 +- g/os/gproc/gproc.go | 10 +++++--- g/os/gproc/gproc_comm.go | 4 ++- g/os/gproc/gproc_manager.go | 37 --------------------------- g/os/gproc/gproc_proccess.go | 48 +++++++++++++++++++++++++++++++++--- g/os/gtime/gtime.go | 6 ++++- geg/other/test.go | 3 +-- 8 files changed, 64 insertions(+), 50 deletions(-) diff --git a/TODO b/TODO index 64173de24..d2e58590a 100644 --- a/TODO +++ b/TODO @@ -9,6 +9,10 @@ orm增加更多数据库支持; ghttp.Response增加输出内容后自动退出当前请求机制,不需要用户手动return,参考beego如何实现; Cookie&Session数据池化处理; ghttp.Client增加proxy特性; +gtime增加对时区转换的封装,并简化失去转换时对类似+80500时区的支持; +改进gf-orm的where查询功能,参考thinkphp 里的where查询语法; + + DONE: 1. gconv完善针对不同类型的判断,例如:尽量减少sprintf("%v", xxx)来执行string类型的转换; diff --git a/g/os/gcmd/gcmd.go b/g/os/gcmd/gcmd.go index d3ff1ce0b..9dac2ba7a 100644 --- a/g/os/gcmd/gcmd.go +++ b/g/os/gcmd/gcmd.go @@ -110,7 +110,7 @@ func (c *gCmdOption) GetBool(key string) bool { return false } -// 绑定命令行参数及对应的命令函数,注意参数是函数的内存地址 +// 绑定命令行参数及对应的命令函数,注意命令函数参数是函数的内存地址 // 如果操作失败返回错误信息 func BindHandle (cmd string, f func()) error { if _, ok := cmdFuncMap[cmd]; ok { diff --git a/g/os/gproc/gproc.go b/g/os/gproc/gproc.go index cd223c12a..ac17cf2b0 100644 --- a/g/os/gproc/gproc.go +++ b/g/os/gproc/gproc.go @@ -17,8 +17,9 @@ import ( ) const ( - gPROC_ENV_KEY_PPID_KEY = "gproc.ppid" - gPROC_TEMP_DIR_ENV_KEY = "gproc.tempdir" + gPROC_ENV_KEY_PPID_KEY = "GPROC_PPID" + gPROC_ENV_KEY_COMM_KEY = "GPROC_COMM_ENABLED" + gPROC_TEMP_DIR_ENV_KEY = "GPROC_TEMP_DIR" ) // 进程开始执行时间 @@ -36,7 +37,7 @@ func PPid() int { } // gPROC_ENV_KEY_PPID_KEY为gproc包自定义的父进程 ppidValue := os.Getenv(gPROC_ENV_KEY_PPID_KEY) - if ppidValue != "" { + if ppidValue != "" && ppidValue != "0" { return gconv.Int(ppidValue) } return PPidOS() @@ -49,7 +50,8 @@ func PPidOS() int { // 判断当前进程是否为gproc创建的子进程 func IsChild() bool { - return os.Getenv(gPROC_ENV_KEY_PPID_KEY) != "" + ppidValue := os.Getenv(gPROC_ENV_KEY_PPID_KEY) + return ppidValue != "" && ppidValue != "0" } // 设置gproc父进程ID,当ppid为0时表示该进程为gproc主进程,否则为gproc子进程 diff --git a/g/os/gproc/gproc_comm.go b/g/os/gproc/gproc_comm.go index 4bb548de6..c80135feb 100644 --- a/g/os/gproc/gproc_comm.go +++ b/g/os/gproc/gproc_comm.go @@ -37,7 +37,9 @@ type sendQueueItem struct { // 进程管理/通信初始化操作 func init() { - go startTcpListening() + if os.Getenv(gPROC_ENV_KEY_COMM_KEY) == "1" { + go startTcpListening() + } } // 获取指定进程的通信文件地址 diff --git a/g/os/gproc/gproc_manager.go b/g/os/gproc/gproc_manager.go index 977c855c7..ed12d4ac7 100644 --- a/g/os/gproc/gproc_manager.go +++ b/g/os/gproc/gproc_manager.go @@ -9,10 +9,7 @@ package gproc import ( "os" - "strings" - "os/exec" "gitee.com/johng/gf/g/container/gmap" - "fmt" ) // 进程管理器 @@ -27,40 +24,6 @@ func NewManager() *Manager { } } -// 创建一个进程(不执行) -func NewProcess(path string, args []string, environment []string) *Process { - env := make([]string, len(environment) + 1) - for k, v := range environment { - env[k] = v - } - env[len(env) - 1] = fmt.Sprintf("%s=%s", gPROC_TEMP_DIR_ENV_KEY, os.TempDir()) - p := &Process { - Manager : nil, - PPid : os.Getpid(), - Cmd : exec.Cmd { - Args : []string{path}, - Path : path, - Stdin : os.Stdin, - Stdout : os.Stdout, - Stderr : os.Stderr, - Env : env, - ExtraFiles : make([]*os.File, 0), - }, - } - // 当前工作目录 - if d, err := os.Getwd(); err == nil { - p.Dir = d - } - if len(args) > 0 { - start := 0 - if strings.EqualFold(path, args[0]) { - start = 1 - } - p.Args = append(p.Args, args[start : ]...) - } - return p -} - // 创建一个进程(不执行) func (m *Manager) NewProcess(path string, args []string, environment []string) *Process { p := NewProcess(path, args, environment) diff --git a/g/os/gproc/gproc_proccess.go b/g/os/gproc/gproc_proccess.go index 4db879f50..7ffab8295 100644 --- a/g/os/gproc/gproc_proccess.go +++ b/g/os/gproc/gproc_proccess.go @@ -11,13 +11,50 @@ import ( "fmt" "os/exec" "errors" + "strings" ) // 子进程 type Process struct { exec.Cmd - Manager *Manager // 所属进程管理器 - PPid int // 自定义关联的父进程ID + Manager *Manager // 所属进程管理器 + PPid int // 自定义关联的父进程ID + CommEnabled bool // 是否开启TCP通信监听服务 +} + +// 创建一个进程(不执行) +func NewProcess(path string, args []string, environment []string) *Process { + env := make([]string, len(environment) + 1) + for k, v := range environment { + env[k] = v + } + env[len(env) - 1] = fmt.Sprintf("%s=%s", gPROC_TEMP_DIR_ENV_KEY, os.TempDir()) + p := &Process { + Manager : nil, + PPid : os.Getpid(), + CommEnabled : true, + Cmd : exec.Cmd { + Args : []string{path}, + Path : path, + Stdin : os.Stdin, + Stdout : os.Stdout, + Stderr : os.Stderr, + Env : env, + ExtraFiles : make([]*os.File, 0), + }, + } + // 当前工作目录 + if d, err := os.Getwd(); err == nil { + p.Dir = d + } + if len(args) > 0 { + start := 0 + if strings.EqualFold(path, args[0]) { + start = 1 + } + p.Args = append(p.Args, args[start : ]...) + } + return p } // 开始执行(非阻塞) @@ -25,9 +62,12 @@ func (p *Process) Start() (int, error) { if p.Process != nil { return p.Pid(), nil } - if p.PPid > 0 { - p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_PPID_KEY, p.PPid)) + commEnabled := 0 + if p.CommEnabled { + commEnabled = 1 } + p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_PPID_KEY, p.PPid)) + p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_COMM_KEY, commEnabled)) if err := p.Cmd.Start(); err == nil { if p.Manager != nil { p.Manager.processes.Set(p.Process.Pid, p) diff --git a/g/os/gtime/gtime.go b/g/os/gtime/gtime.go index 889e62e3b..5a1214511 100644 --- a/g/os/gtime/gtime.go +++ b/g/os/gtime/gtime.go @@ -15,6 +15,10 @@ import ( "errors" ) +const ( + TIME_REAGEX_PATTERN = `(\d{4}-\d{2}-\d{2})[\sT]{0,1}(\d{2}:\d{2}:\d{2}){0,1}\.{0,1}(\d{0,9})([\sZ]{0,1})([\+-]{0,1})([:\d]*)` +) + var ( // 用于time.Time转换使用,防止多次Compile timeRegex *regexp.Regexp @@ -22,7 +26,7 @@ var ( func init() { // 使用正则判断会比直接使用ParseInLocation挨个轮训判断要快很多 - timeRegex, _ = regexp.Compile(`(\d{4}-\d{2}-\d{2})[\sT]{0,1}(\d{2}:\d{2}:\d{2}){0,1}\.{0,1}(\d{0,9})([\sZ]{0,1})([\+-]{0,1})([:\d]*)`) + timeRegex, _ = regexp.Compile(TIME_REAGEX_PATTERN) } diff --git a/geg/other/test.go b/geg/other/test.go index 7b38824b0..5d0e543e1 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -8,5 +8,4 @@ import ( func main() { fmt.Println(gconv.Float64(float32(19.66))) fmt.Println(float64(float32(19.66))) - -} \ No newline at end of file +} From 335da384fee40647d863098c7e83aca91510537b Mon Sep 17 00:00:00 2001 From: john Date: Fri, 29 Jun 2018 13:53:14 +0800 Subject: [PATCH 05/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8DLinux=E4=B8=8B=E7=9A=84?= =?UTF-8?q?=E5=B9=B3=E6=BB=91=E9=87=8D=E5=90=AF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO | 2 +- g/net/ghttp/ghttp_server_admin.go | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index d2e58590a..a1ee9dcca 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ Cookie&Session数据池化处理; ghttp.Client增加proxy特性; gtime增加对时区转换的封装,并简化失去转换时对类似+80500时区的支持; 改进gf-orm的where查询功能,参考thinkphp 里的where查询语法; - +改进ghttp.Server平滑重启机制,当新进程接管服务后,再使用进程间通信方式通知父进程销毁; DONE: diff --git a/g/net/ghttp/ghttp_server_admin.go b/g/net/ghttp/ghttp_server_admin.go index 95610013d..48f6fa95c 100644 --- a/g/net/ghttp/ghttp_server_admin.go +++ b/g/net/ghttp/ghttp_server_admin.go @@ -240,8 +240,11 @@ func restartWebServers(newExeFilePath...string) { }) } else { forkReloadProcess(newExeFilePath...) - go gracefulShutdownWebServers() - doneChan <- struct{}{} + // 异步2秒后再执行关闭,目的是让新进程将服务成功接管后,再关闭自身进程(后续可以根据进程间通信来改进) + gtime.SetTimeout(2*time.Second, func() { + go gracefulShutdownWebServers() + doneChan <- struct{}{} + }) } } From 4fcde33eb48ed4ad8c8173aab24e26442321b8fb Mon Sep 17 00:00:00 2001 From: John Date: Fri, 29 Jun 2018 17:26:34 +0800 Subject: [PATCH 06/18] =?UTF-8?q?=E6=94=B9=E8=BF=9Bghttp.Server=E5=B9=B3?= =?UTF-8?q?=E6=BB=91=E9=87=8D=E5=90=AF=E8=BF=9B=E7=A8=8B=E9=97=B4=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/net/ghttp/ghttp_server.go | 11 +++++++++++ g/net/ghttp/ghttp_server_admin.go | 23 ++++++++++++++++------- g/os/gproc/gproc_comm.go | 3 ++- g/os/gproc/gproc_proccess.go | 9 ++++----- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index ee2cdf69b..eae67dac5 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -25,6 +25,8 @@ import ( "gitee.com/johng/gf/g/os/gfile" "gitee.com/johng/gf/g/os/genv" "github.com/gorilla/websocket" + "gitee.com/johng/gf/g/os/gtime" + "time" ) const ( @@ -127,6 +129,8 @@ func init() { // 信号量管理操作监听 go handleProcessSignal() + // 异步监听进程间消息 + go handleProcessMessage() } // 获取/创建一个默认配置的HTTP Server(默认监听端口是80) @@ -213,6 +217,13 @@ func (s *Server) Start() error { s.startServer(nil) } + // 如果是子进程,那么服务开启后通知父进程销毁 + if gproc.IsChild() { + gtime.SetTimeout(2*time.Second, func() { + gproc.Send(gproc.PPid(), []byte("exit")) + }) + } + // 开启异步关闭队列处理循环 s.startCloseQueueLoop() return nil diff --git a/g/net/ghttp/ghttp_server_admin.go b/g/net/ghttp/ghttp_server_admin.go index 48f6fa95c..bd1de1edb 100644 --- a/g/net/ghttp/ghttp_server_admin.go +++ b/g/net/ghttp/ghttp_server_admin.go @@ -22,14 +22,15 @@ import ( "gitee.com/johng/gf/g/util/gconv" "time" "runtime" + "bytes" ) const ( gADMIN_ACTION_INTERVAL_LIMIT = 2000 // (毫秒)服务开启后允许执行管理操作的间隔限制 gADMIN_ACTION_RESTARTING = 1 gADMIN_ACTION_SHUTINGDOWN = 2 - gADMIN_ACTION_RELOAD_ENVKEY = "gf.server.reload" - gADMIN_ACTION_RESTART_ENVKEY = "gf.server.restart" + gADMIN_ACTION_RELOAD_ENVKEY = "GF_SERVER_RELOAD" + gADMIN_ACTION_RESTART_ENVKEY = "GF_SERVER_RESTART" ) // 用于服务管理的对象 @@ -240,11 +241,6 @@ func restartWebServers(newExeFilePath...string) { }) } else { forkReloadProcess(newExeFilePath...) - // 异步2秒后再执行关闭,目的是让新进程将服务成功接管后,再关闭自身进程(后续可以根据进程间通信来改进) - gtime.SetTimeout(2*time.Second, func() { - go gracefulShutdownWebServers() - doneChan <- struct{}{} - }) } } @@ -281,4 +277,17 @@ func forcedlyCloseWebServers() { } } }) +} + +// 异步监听进程间消息 +func handleProcessMessage() { + for { + if msg := gproc.Receive(); msg != nil { + if bytes.EqualFold(msg.Data, []byte("exit")) { + gracefulShutdownWebServers() + doneChan <- struct{}{} + return + } + } + } } \ No newline at end of file diff --git a/g/os/gproc/gproc_comm.go b/g/os/gproc/gproc_comm.go index c80135feb..257981b65 100644 --- a/g/os/gproc/gproc_comm.go +++ b/g/os/gproc/gproc_comm.go @@ -37,7 +37,8 @@ type sendQueueItem struct { // 进程管理/通信初始化操作 func init() { - if os.Getenv(gPROC_ENV_KEY_COMM_KEY) == "1" { + // 默认下为空("") + if os.Getenv(gPROC_ENV_KEY_COMM_KEY) != "0" { go startTcpListening() } } diff --git a/g/os/gproc/gproc_proccess.go b/g/os/gproc/gproc_proccess.go index 7ffab8295..654ca0796 100644 --- a/g/os/gproc/gproc_proccess.go +++ b/g/os/gproc/gproc_proccess.go @@ -19,7 +19,7 @@ type Process struct { exec.Cmd Manager *Manager // 所属进程管理器 PPid int // 自定义关联的父进程ID - CommEnabled bool // 是否开启TCP通信监听服务 + DisableComm bool // 是否关闭TCP通信监听服务 } // 创建一个进程(不执行) @@ -32,7 +32,6 @@ func NewProcess(path string, args []string, environment []string) *Process { p := &Process { Manager : nil, PPid : os.Getpid(), - CommEnabled : true, Cmd : exec.Cmd { Args : []string{path}, Path : path, @@ -62,9 +61,9 @@ func (p *Process) Start() (int, error) { if p.Process != nil { return p.Pid(), nil } - commEnabled := 0 - if p.CommEnabled { - commEnabled = 1 + commEnabled := 1 + if p.DisableComm { + commEnabled = 0 } p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_PPID_KEY, p.PPid)) p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_COMM_KEY, commEnabled)) From 5db9bc33ef9a3af4d9d5fee94921a395a4fc0e29 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 30 Jun 2018 22:50:21 +0800 Subject: [PATCH 07/18] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO | 3 +- .../gmap/{gmap_test.go => gmap_bench_test.go} | 23 ++++++------ g/container/gmap/int_interface_map.go | 36 +++++++++++++++++++ g/encoding/gjson/gjson.go | 6 +++- g/encoding/gparser/gparser.go | 6 ++-- g/net/ghttp/ghttp_server_cookie.go | 8 ++--- g/net/ghttp/ghttp_server_session.go | 4 +++ g/os/gtime/gtime.go | 9 +++++ g/util/gconv/gconv.go | 9 +++-- geg/other/test.go | 7 ++-- 10 files changed, 84 insertions(+), 27 deletions(-) rename g/container/gmap/{gmap_test.go => gmap_bench_test.go} (78%) diff --git a/TODO b/TODO index a1ee9dcca..e37de6cb1 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ Cookie&Session数据池化处理; ghttp.Client增加proxy特性; gtime增加对时区转换的封装,并简化失去转换时对类似+80500时区的支持; 改进gf-orm的where查询功能,参考thinkphp 里的where查询语法; -改进ghttp.Server平滑重启机制,当新进程接管服务后,再使用进程间通信方式通知父进程销毁; + DONE: @@ -40,6 +40,7 @@ DONE: 23. 平滑重启机制改进,以便于开发阶段调试; 24. 对grpool进行优化改进,包括属性原子操作封装采用gtype实现,修正设计BUG:https://github.com/johng-cn/gf/issues/6; 25. gredis增加redis密码支持; +26. 改进ghttp.Server平滑重启机制,当新进程接管服务后,再使用进程间通信方式通知父进程销毁; diff --git a/g/container/gmap/gmap_test.go b/g/container/gmap/gmap_bench_test.go similarity index 78% rename from g/container/gmap/gmap_test.go rename to g/container/gmap/gmap_bench_test.go index 8291ef0f5..ccba0b6b0 100644 --- a/g/container/gmap/gmap_test.go +++ b/g/container/gmap/gmap_bench_test.go @@ -6,25 +6,24 @@ // go test *.go -bench=".*" -package gmap_test +package gmap import ( "testing" - "gitee.com/johng/gf/g/container/gmap" "strconv" ) -var ibm = gmap.NewIntBoolMap() -var iim = gmap.NewIntIntMap() -var iifm = gmap.NewIntInterfaceMap() -var ism = gmap.NewIntStringMap() -var ififm = gmap.NewInterfaceInterfaceMap() -var sbm = gmap.NewStringBoolMap() -var sim = gmap.NewStringIntMap() -var sifm = gmap.NewStringInterfaceMap() -var ssm = gmap.NewStringStringMap() -var uifm = gmap.NewUintInterfaceMap() +var ibm = NewIntBoolMap() +var iim = NewIntIntMap() +var iifm = NewIntInterfaceMap() +var ism = NewIntStringMap() +var ififm = NewInterfaceInterfaceMap() +var sbm = NewStringBoolMap() +var sim = NewStringIntMap() +var sifm = NewStringInterfaceMap() +var ssm = NewStringStringMap() +var uifm = NewUintInterfaceMap() func BenchmarkIntBoolMap_Set(b *testing.B) { for i := 0; i < b.N; i++ { diff --git a/g/container/gmap/int_interface_map.go b/g/container/gmap/int_interface_map.go index d36eed4e5..708598771 100644 --- a/g/container/gmap/int_interface_map.go +++ b/g/container/gmap/int_interface_map.go @@ -89,10 +89,42 @@ func (this *IntInterfaceMap) GetInt(key int) int { return gconv.Int(this.Get(key)) } +func (this *IntInterfaceMap) GetInt8(key int) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *IntInterfaceMap) GetInt16(key int) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *IntInterfaceMap) GetInt32(key int) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *IntInterfaceMap) GetInt64(key int) int64 { + return gconv.Int64(this.Get(key)) +} + func (this *IntInterfaceMap) GetUint (key int) uint { return gconv.Uint(this.Get(key)) } +func (this *IntInterfaceMap) GetUint8 (key int) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *IntInterfaceMap) GetUint16 (key int) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *IntInterfaceMap) GetUint32 (key int) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *IntInterfaceMap) GetUint64 (key int) uint64 { + return gconv.Uint64(this.Get(key)) +} + func (this *IntInterfaceMap) GetFloat32 (key int) float32 { return gconv.Float32(this.Get(key)) } @@ -105,6 +137,10 @@ func (this *IntInterfaceMap) GetString (key int) string { return gconv.String(this.Get(key)) } +func (this *IntInterfaceMap) GetStrings (key int) []string { + return gconv.Strings(this.Get(key)) +} + // 删除键值对 func (this *IntInterfaceMap) Remove(key int) { this.mu.Lock() diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index b1fecc7c1..24dd51d50 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -101,9 +101,13 @@ func Load (path string) (*Json, error) { } // 支持的配置文件格式:xml, json, yaml/yml, toml -func LoadContent (data []byte, t string) (*Json, error) { +func LoadContent (data []byte, dataType...string) (*Json, error) { var err error var result interface{} + t := "json" + if len(dataType) > 0 { + t = dataType[0] + } switch t { case "xml": fallthrough case ".xml": diff --git a/g/encoding/gparser/gparser.go b/g/encoding/gparser/gparser.go index d4588d7cd..a711ef466 100644 --- a/g/encoding/gparser/gparser.go +++ b/g/encoding/gparser/gparser.go @@ -32,9 +32,9 @@ func Load (path string) (*Parser, error) { } } -// 支持的配置文件格式:xml, json, yaml/yml, toml -func LoadContent (data []byte, fileType string) (*Parser, error) { - if j, e := gjson.LoadContent(data, fileType); e == nil { +// 支持的数据内容格式:json(默认), xml, yaml/yml, toml +func LoadContent (data []byte, dataType...string) (*Parser, error) { + if j, e := gjson.LoadContent(data, dataType...); e == nil { return &Parser{j}, nil } else { return nil, e diff --git a/g/net/ghttp/ghttp_server_cookie.go b/g/net/ghttp/ghttp_server_cookie.go index 363d57779..df0a78a18 100644 --- a/g/net/ghttp/ghttp_server_cookie.go +++ b/g/net/ghttp/ghttp_server_cookie.go @@ -12,7 +12,6 @@ package ghttp import ( "sync" "time" - "strings" "net/http" "gitee.com/johng/gf/g/os/gtime" ) @@ -43,7 +42,7 @@ func GetCookie(r *Request) *Cookie { } c := &Cookie { data : make(map[string]CookieItem), - domain : strings.Split(r.Host, ":")[0], + domain : r.GetHost(), server : r.Server, request : r, response : r.Response, @@ -53,15 +52,13 @@ func GetCookie(r *Request) *Cookie { return c } -// 从请求流中初始化 +// 从请求流中初始化,无锁 func (c *Cookie) init() { - c.mu.Lock() for _, v := range c.request.Cookies() { c.data[v.Name] = CookieItem { v.Value, v.Domain, v.Path, v.Expires.Second(), v.HttpOnly, } } - c.mu.Unlock() } // 获取所有的Cookie并构造成map返回 @@ -137,6 +134,7 @@ func (c *Cookie) Close() { func (c *Cookie) Output() { c.mu.RLock() for k, v := range c.data { + // 只有expire != 0的才是服务端在本地请求中设置的cookie if v.expire == 0 { continue } diff --git a/g/net/ghttp/ghttp_server_session.go b/g/net/ghttp/ghttp_server_session.go index e043596ab..418ce1c98 100644 --- a/g/net/ghttp/ghttp_server_session.go +++ b/g/net/ghttp/ghttp_server_session.go @@ -86,6 +86,10 @@ func (s *Session) GetUint (k string) uint { return gconv.Uint(s.Get(k)) } +func (s *Session) GetUint8 (k string) uint8 { + return gconv.Uint8(s.Get(k)) +} + func (s *Session) GetFloat32 (k string) float32 { return gconv.Float32(s.Get(k)) } diff --git a/g/os/gtime/gtime.go b/g/os/gtime/gtime.go index 5a1214511..a61da09c3 100644 --- a/g/os/gtime/gtime.go +++ b/g/os/gtime/gtime.go @@ -92,6 +92,15 @@ func Format(format string, timestamps...int64) string { } // 字符串转换为时间对象,需要给定字符串时间格式,format格式形如:2006-01-02 15:04:05 +// 不传递自定义格式下默认支持的标准时间格式: +// "2017-12-14 04:51:34 +0805 LMT", +// "2006-01-02T15:04:05Z07:00", +// "2014-01-17T01:19:15+08:00", +// "2018-02-09T20:46:17.897Z", +// "2018-02-09 20:46:17.897", +// "2018-02-09T20:46:17Z", +// "2018-02-09 20:46:17", +// "2018-02-09", func StrToTime(str string, format...string) (time.Time, error) { // 优先使用用户输入日期格式进行转换 if len(format) > 0 { diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 1b3f6903d..98ab9a7e1 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -18,7 +18,7 @@ import ( ) // 将变量i转换为字符串指定的类型t -func Convert(i interface{}, t string) interface{} { +func Convert(i interface{}, t string, params...interface{}) interface{} { switch t { case "int": return Int(i) case "int8": return Int8(i) @@ -35,7 +35,12 @@ func Convert(i interface{}, t string) interface{} { case "bool": return Bool(i) case "string": return String(i) case "[]byte": return Bytes(i) - case "time.Time": return Time(i) + case "time.Time": + if len(params) > 0 { + return Time(i, String(params[0])) + } + return Time(i) + case "time.Duration": return TimeDuration(i) default: return i diff --git a/geg/other/test.go b/geg/other/test.go index 5d0e543e1..2a09e7127 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,10 +2,11 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/encoding/gjson" ) func main() { - fmt.Println(gconv.Float64(float32(19.66))) - fmt.Println(float64(float32(19.66))) + content := `[0.00000000059, 1.598877777409]` + j, _ := gjson.LoadContent([]byte(content), "json") + fmt.Println(j.GetString("0")) } From 997e1cf39283a0cff0e4867d0a564ec7c6dbce81 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 30 Jun 2018 22:52:39 +0800 Subject: [PATCH 08/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgdb=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AESave=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/database/gdb/gdb_base.go | 2 +- g/database/gdb/gdb_transaction.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/g/database/gdb/gdb_base.go b/g/database/gdb/gdb_base.go index cc02d4518..dbaba6c1f 100644 --- a/g/database/gdb/gdb_base.go +++ b/g/database/gdb/gdb_base.go @@ -290,7 +290,7 @@ func (db *Db) batchInsert(table string, list List, batch int, option uint8) (sql if option == OPTION_SAVE { var updates []string for _, k := range keys { - updates = append(updates, fmt.Sprintf("%s=VALUES(%s)", db.charl, k, db.charr, k)) + updates = append(updates, fmt.Sprintf("%s%s%s=VALUES(%s)", db.charl, k, db.charr, k)) } updatestr = fmt.Sprintf(" ON DUPLICATE KEY UPDATE %s", strings.Join(updates, ",")) } diff --git a/g/database/gdb/gdb_transaction.go b/g/database/gdb/gdb_transaction.go index 4cba7163e..9014ba6fc 100644 --- a/g/database/gdb/gdb_transaction.go +++ b/g/database/gdb/gdb_transaction.go @@ -225,7 +225,7 @@ func (tx *Tx) batchInsert(table string, list List, batch int, option uint8) (sql if option == OPTION_SAVE { var updates []string for _, k := range keys { - updates = append(updates, fmt.Sprintf("%s=VALUES(%s)", tx.db.charl, k, tx.db.charr, k)) + updates = append(updates, fmt.Sprintf("%s%s%s=VALUES(%s)", tx.db.charl, k, tx.db.charr, k)) } updatestr = fmt.Sprintf(" ON DUPLICATE KEY UPDATE %s", strings.Join(updates, ",")) } From cfad36ea0b329e50f26bd995bab401282f406e55 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 30 Jun 2018 23:12:37 +0800 Subject: [PATCH 09/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgdb=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AESave=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/database/gdb/gdb_base.go | 16 ++++++++++++---- g/database/gdb/gdb_transaction.go | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/g/database/gdb/gdb_base.go b/g/database/gdb/gdb_base.go index dbaba6c1f..48817a5b4 100644 --- a/g/database/gdb/gdb_base.go +++ b/g/database/gdb/gdb_base.go @@ -283,7 +283,8 @@ func (db *Db) batchInsert(table string, list List, batch int, option uint8) (sql keys = append(keys, k) values = append(values, "?") } - var kstr = db.charl + strings.Join(keys, db.charl + "," + db.charr) + db.charr + keyStr := db.charl + strings.Join(keys, db.charl + "," + db.charr) + db.charr + valueHolderStr := "(" + strings.Join(values, ",") + ")" // 操作判断 operation := db.getInsertOperationByOption(option) updatestr := "" @@ -299,19 +300,26 @@ func (db *Db) batchInsert(table string, list List, batch int, option uint8) (sql for _, k := range keys { params = append(params, list[i][k]) } - bvalues = append(bvalues, "(" + strings.Join(values, ",") + ")") + bvalues = append(bvalues, valueHolderStr) if len(bvalues) == batch { - r, err := db.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, db.charl, table, db.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) + r, err := db.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", + operation, db.charl, table, db.charr, keyStr, strings.Join(bvalues, ","), + updatestr), + params...) if err != nil { return result, err } result = r + params = params[:0] bvalues = bvalues[:0] } } // 处理最后不构成指定批量的数据 if len(bvalues) > 0 { - r, err := db.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, db.charl, table, db.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) + r, err := db.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", + operation, db.charl, table, db.charr, keyStr, strings.Join(bvalues, ","), + updatestr), + params...) if err != nil { return result, err } diff --git a/g/database/gdb/gdb_transaction.go b/g/database/gdb/gdb_transaction.go index 9014ba6fc..64023107d 100644 --- a/g/database/gdb/gdb_transaction.go +++ b/g/database/gdb/gdb_transaction.go @@ -218,7 +218,8 @@ func (tx *Tx) batchInsert(table string, list List, batch int, option uint8) (sql keys = append(keys, k) values = append(values, "?") } - var kstr = tx.db.charl + strings.Join(keys, tx.db.charl + "," + tx.db.charr) + tx.db.charr + keyStr := tx.db.charl + strings.Join(keys, tx.db.charl + "," + tx.db.charr) + tx.db.charr + valueHolderStr := "(" + strings.Join(values, ",") + ")" // 操作判断 operation := tx.db.getInsertOperationByOption(option) updatestr := "" @@ -234,19 +235,26 @@ func (tx *Tx) batchInsert(table string, list List, batch int, option uint8) (sql for _, k := range keys { params = append(params, list[i][k]) } - bvalues = append(bvalues, "(" + strings.Join(values, ",") + ")") + bvalues = append(bvalues, valueHolderStr) if len(bvalues) == batch { - r, err := tx.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, tx.db.charl, table, tx.db.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) + r, err := tx.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", + operation, tx.db.charl, table, tx.db.charr, keyStr, strings.Join(bvalues, ","), + updatestr), + params...) if err != nil { return result, err } result = r + params = params[:0] bvalues = bvalues[:0] } } // 处理最后不构成指定批量的数据 if len(bvalues) > 0 { - r, err := tx.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, tx.db.charl, table, tx.db.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) + r, err := tx.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", + operation, tx.db.charl, table, tx.db.charr, kstr, strings.Join(bvalues, ","), + updatestr), + params...) if err != nil { return result, err } From c9deec8e04194e427bc9ffa124e0d11bc8459147 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 30 Jun 2018 23:14:54 +0800 Subject: [PATCH 10/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgdb=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AESave=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/database/gdb/gdb_transaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g/database/gdb/gdb_transaction.go b/g/database/gdb/gdb_transaction.go index 64023107d..365bbb92c 100644 --- a/g/database/gdb/gdb_transaction.go +++ b/g/database/gdb/gdb_transaction.go @@ -252,7 +252,7 @@ func (tx *Tx) batchInsert(table string, list List, batch int, option uint8) (sql // 处理最后不构成指定批量的数据 if len(bvalues) > 0 { r, err := tx.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", - operation, tx.db.charl, table, tx.db.charr, kstr, strings.Join(bvalues, ","), + operation, tx.db.charl, table, tx.db.charr, keyStr, strings.Join(bvalues, ","), updatestr), params...) if err != nil { From ebbbefcaf594db3cc5c63e7192bf8f4fb8dd929a Mon Sep 17 00:00:00 2001 From: John Date: Sun, 1 Jul 2018 00:27:33 +0800 Subject: [PATCH 11/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A1=86=E6=9E=B6gmap/?= =?UTF-8?q?gjson/gparser/gcfg=E5=8C=85=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=B8=B8?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E5=9F=BA=E6=9C=AC=E6=95=B0=E6=8D=AE=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=BD=AC=E6=8D=A2=E8=8E=B7=E5=8F=96=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/garray/garray_interface.go | 8 +-- g/container/garray/garray_sorted_int.go | 4 +- g/container/garray/garray_sorted_interface.go | 4 +- g/container/garray/garray_sorted_string.go | 4 +- g/container/gmap/int_int_map.go | 68 +++++++++++++++++- g/container/gmap/int_interface_map.go | 9 +++ g/container/gmap/int_string_map.go | 66 +++++++++++++++++ g/container/gmap/interface_interface_map.go | 45 ++++++++++++ g/container/gmap/string_int_map.go | 70 +++++++++++++++++++ g/container/gmap/string_interface_map.go | 57 +++++++++++++-- g/container/gmap/string_string_map.go | 70 +++++++++++++++++++ g/container/gmap/uint_interface_map.go | 46 +++++++++++- g/encoding/gjson/gjson.go | 41 ++++++++--- g/encoding/gparser/gparser.go | 23 ++++-- g/os/gcfg/gcfg.go | 7 ++ 15 files changed, 488 insertions(+), 34 deletions(-) diff --git a/g/container/garray/garray_interface.go b/g/container/garray/garray_interface.go index 5699740f0..a74be51f4 100644 --- a/g/container/garray/garray_interface.go +++ b/g/container/garray/garray_interface.go @@ -30,32 +30,32 @@ func NewArray(size int, cap ... int) *Array { // 获取指定索引的数据项, 调用方注意判断数组边界 func (a *Array) Get(index int) interface{} { a.mu.RLock() + defer a.mu.RUnlock() value := a.array[index] - a.mu.RUnlock() return value } // 设置指定索引的数据项, 调用方注意判断数组边界 func (a *Array) Set(index int, value interface{}) { a.mu.Lock() + defer a.mu.Unlock() a.array[index] = value - a.mu.Unlock() } // 在当前索引位置前插入一个数据项, 调用方注意判断数组边界 func (a *Array) Insert(index int, value interface{}) { a.mu.Lock() + defer a.mu.Unlock() rear := append([]interface{}{}, a.array[index : ]...) a.array = append(a.array[0 : index], value) a.array = append(a.array, rear...) - a.mu.Unlock() } // 删除指定索引的数据项, 调用方注意判断数组边界 func (a *Array) Remove(index int) { a.mu.Lock() + defer a.mu.Unlock() a.array = append(a.array[ : index], a.array[index + 1 : ]...) - a.mu.Unlock() } // 追加数据项 diff --git a/g/container/garray/garray_sorted_int.go b/g/container/garray/garray_sorted_int.go index 1651b47cb..bdeca5460 100644 --- a/g/container/garray/garray_sorted_int.go +++ b/g/container/garray/garray_sorted_int.go @@ -70,16 +70,16 @@ func (a *SortedIntArray) Add(value int) { // 获取指定索引的数据项, 调用方注意判断数组边界 func (a *SortedIntArray) Get(index int) int { a.mu.RLock() + defer a.mu.RUnlock() value := a.array[index] - a.mu.RUnlock() return value } // 删除指定索引的数据项, 调用方注意判断数组边界 func (a *SortedIntArray) Remove(index int) { a.mu.Lock() + defer a.mu.Unlock() a.array = append(a.array[ : index], a.array[index + 1 : ]...) - a.mu.Unlock() } // 数组长度 diff --git a/g/container/garray/garray_sorted_interface.go b/g/container/garray/garray_sorted_interface.go index 35eeaa259..3e8704bea 100644 --- a/g/container/garray/garray_sorted_interface.go +++ b/g/container/garray/garray_sorted_interface.go @@ -55,16 +55,16 @@ func (a *SortedArray) Add(value interface{}) { // 获取指定索引的数据项, 调用方注意判断数组边界 func (a *SortedArray) Get(index int) interface{} { a.mu.RLock() + defer a.mu.RUnlock() value := a.array[index] - a.mu.RUnlock() return value } // 删除指定索引的数据项, 调用方注意判断数组边界 func (a *SortedArray) Remove(index int) { a.mu.Lock() + defer a.mu.Unlock() a.array = append(a.array[ : index], a.array[index + 1 : ]...) - a.mu.Unlock() } // 数组长度 diff --git a/g/container/garray/garray_sorted_string.go b/g/container/garray/garray_sorted_string.go index a3fc76e47..020866515 100644 --- a/g/container/garray/garray_sorted_string.go +++ b/g/container/garray/garray_sorted_string.go @@ -65,16 +65,16 @@ func (a *SortedStringArray) Add(value string) { // 获取指定索引的数据项, 调用方注意判断数组边界 func (a *SortedStringArray) Get(index int) string { a.mu.RLock() + defer a.mu.RUnlock() value := a.array[index] - a.mu.RUnlock() return value } // 删除指定索引的数据项, 调用方注意判断数组边界 func (a *SortedStringArray) Remove(index int) { a.mu.Lock() + defer a.mu.Unlock() a.array = append(a.array[ : index], a.array[index + 1 : ]...) - a.mu.Unlock() } // 数组长度 diff --git a/g/container/gmap/int_int_map.go b/g/container/gmap/int_int_map.go index dea27f0e4..a1f87951e 100644 --- a/g/container/gmap/int_int_map.go +++ b/g/container/gmap/int_int_map.go @@ -9,6 +9,8 @@ package gmap import ( "sync" + "gitee.com/johng/gf/g/util/gconv" + "time" ) type IntIntMap struct { @@ -68,6 +70,70 @@ func (this *IntIntMap) Get(key int) (int) { return val } +func (this *IntIntMap) GetBool(key int) bool { + return gconv.Bool(this.Get(key)) +} + +func (this *IntIntMap) GetInt(key int) int { + return gconv.Int(this.Get(key)) +} + +func (this *IntIntMap) GetInt8(key int) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *IntIntMap) GetInt16(key int) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *IntIntMap) GetInt32(key int) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *IntIntMap) GetInt64(key int) int64 { + return gconv.Int64(this.Get(key)) +} + +func (this *IntIntMap) GetUint (key int) uint { + return gconv.Uint(this.Get(key)) +} + +func (this *IntIntMap) GetUint8 (key int) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *IntIntMap) GetUint16 (key int) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *IntIntMap) GetUint32 (key int) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *IntIntMap) GetUint64 (key int) uint64 { + return gconv.Uint64(this.Get(key)) +} + +func (this *IntIntMap) GetFloat32 (key int) float32 { + return gconv.Float32(this.Get(key)) +} + +func (this *IntIntMap) GetFloat64 (key int) float64 { + return gconv.Float64(this.Get(key)) +} + +func (this *IntIntMap) GetString (key int) string { + return gconv.String(this.Get(key)) +} + +func (this *IntIntMap) GetTime (key int, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *IntIntMap) GetTimeDuration (key int) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 获取键值,如果键值不存在则写入默认值 func (this *IntIntMap) GetWithDefault(key int, value int) int { this.mu.Lock() @@ -148,7 +214,7 @@ func (this *IntIntMap) Size() int { // 哈希表是否为空 func (this *IntIntMap) IsEmpty() bool { this.mu.RLock() - empty := (len(this.m) == 0) + empty := len(this.m) == 0 this.mu.RUnlock() return empty } diff --git a/g/container/gmap/int_interface_map.go b/g/container/gmap/int_interface_map.go index 708598771..dbac2bd67 100644 --- a/g/container/gmap/int_interface_map.go +++ b/g/container/gmap/int_interface_map.go @@ -10,6 +10,7 @@ package gmap import ( "sync" "gitee.com/johng/gf/g/util/gconv" + "time" ) type IntInterfaceMap struct { @@ -141,6 +142,14 @@ func (this *IntInterfaceMap) GetStrings (key int) []string { return gconv.Strings(this.Get(key)) } +func (this *IntInterfaceMap) GetTime (key int, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *IntInterfaceMap) GetTimeDuration (key int) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 删除键值对 func (this *IntInterfaceMap) Remove(key int) { this.mu.Lock() diff --git a/g/container/gmap/int_string_map.go b/g/container/gmap/int_string_map.go index 10b685691..6cde82dc5 100644 --- a/g/container/gmap/int_string_map.go +++ b/g/container/gmap/int_string_map.go @@ -9,6 +9,8 @@ package gmap import ( "sync" + "gitee.com/johng/gf/g/util/gconv" + "time" ) type IntStringMap struct { @@ -68,6 +70,70 @@ func (this *IntStringMap) Get(key int) string { return val } +func (this *IntStringMap) GetBool(key int) bool { + return gconv.Bool(this.Get(key)) +} + +func (this *IntStringMap) GetInt(key int) int { + return gconv.Int(this.Get(key)) +} + +func (this *IntStringMap) GetInt8(key int) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *IntStringMap) GetInt16(key int) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *IntStringMap) GetInt32(key int) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *IntStringMap) GetInt64(key int) int64 { + return gconv.Int64(this.Get(key)) +} + +func (this *IntStringMap) GetUint (key int) uint { + return gconv.Uint(this.Get(key)) +} + +func (this *IntStringMap) GetUint8 (key int) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *IntStringMap) GetUint16 (key int) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *IntStringMap) GetUint32 (key int) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *IntStringMap) GetUint64 (key int) uint64 { + return gconv.Uint64(this.Get(key)) +} + +func (this *IntStringMap) GetFloat32 (key int) float32 { + return gconv.Float32(this.Get(key)) +} + +func (this *IntStringMap) GetFloat64 (key int) float64 { + return gconv.Float64(this.Get(key)) +} + +func (this *IntStringMap) GetString (key int) string { + return gconv.String(this.Get(key)) +} + +func (this *IntStringMap) GetTime (key int, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *IntStringMap) GetTimeDuration (key int) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 获取键值,如果键值不存在则写入默认值 func (this *IntStringMap) GetWithDefault(key int, value string) string { this.mu.Lock() diff --git a/g/container/gmap/interface_interface_map.go b/g/container/gmap/interface_interface_map.go index bdea3c174..437fcee49 100644 --- a/g/container/gmap/interface_interface_map.go +++ b/g/container/gmap/interface_interface_map.go @@ -10,6 +10,7 @@ package gmap import ( "sync" "gitee.com/johng/gf/g/util/gconv" + "time" ) type InterfaceInterfaceMap struct { @@ -89,10 +90,42 @@ func (this *InterfaceInterfaceMap) GetInt(key interface{}) int { return gconv.Int(this.Get(key)) } +func (this *InterfaceInterfaceMap) GetInt8(key interface{}) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetInt16(key interface{}) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetInt32(key interface{}) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetInt64(key interface{}) int64 { + return gconv.Int64(this.Get(key)) +} + func (this *InterfaceInterfaceMap) GetUint (key interface{}) uint { return gconv.Uint(this.Get(key)) } +func (this *InterfaceInterfaceMap) GetUint8 (key interface{}) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetUint16 (key interface{}) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetUint32 (key interface{}) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetUint64 (key interface{}) uint64 { + return gconv.Uint64(this.Get(key)) +} + func (this *InterfaceInterfaceMap) GetFloat32 (key interface{}) float32 { return gconv.Float32(this.Get(key)) } @@ -105,6 +138,18 @@ func (this *InterfaceInterfaceMap) GetString (key interface{}) string { return gconv.String(this.Get(key)) } +func (this *InterfaceInterfaceMap) GetStrings (key interface{}) []string { + return gconv.Strings(this.Get(key)) +} + +func (this *InterfaceInterfaceMap) GetTime (key interface{}, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *InterfaceInterfaceMap) GetTimeDuration (key interface{}) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 删除键值对 func (this *InterfaceInterfaceMap) Remove(key interface{}) { this.mu.Lock() diff --git a/g/container/gmap/string_int_map.go b/g/container/gmap/string_int_map.go index 17487dfc2..ce6dd035d 100644 --- a/g/container/gmap/string_int_map.go +++ b/g/container/gmap/string_int_map.go @@ -9,6 +9,8 @@ package gmap import ( "sync" + "gitee.com/johng/gf/g/util/gconv" + "time" ) type StringIntMap struct { @@ -68,6 +70,74 @@ func (this *StringIntMap) Get(key string) int { return val } +func (this *StringIntMap) GetBool(key string) bool { + return gconv.Bool(this.Get(key)) +} + +func (this *StringIntMap) GetInt(key string) int { + return gconv.Int(this.Get(key)) +} + +func (this *StringIntMap) GetInt8(key string) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *StringIntMap) GetInt16(key string) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *StringIntMap) GetInt32(key string) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *StringIntMap) GetInt64(key string) int64 { + return gconv.Int64(this.Get(key)) +} + +func (this *StringIntMap) GetUint (key string) uint { + return gconv.Uint(this.Get(key)) +} + +func (this *StringIntMap) GetUint8 (key string) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *StringIntMap) GetUint16 (key string) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *StringIntMap) GetUint32 (key string) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *StringIntMap) GetUint64 (key string) uint64 { + return gconv.Uint64(this.Get(key)) +} + +func (this *StringIntMap) GetFloat32 (key string) float32 { + return gconv.Float32(this.Get(key)) +} + +func (this *StringIntMap) GetFloat64 (key string) float64 { + return gconv.Float64(this.Get(key)) +} + +func (this *StringIntMap) GetString (key string) string { + return gconv.String(this.Get(key)) +} + +func (this *StringIntMap) GetStrings (key string) []string { + return gconv.Strings(this.Get(key)) +} + +func (this *StringIntMap) GetTime (key string, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *StringIntMap) GetTimeDuration (key string) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 获取键值,如果键值不存在则写入默认值 func (this *StringIntMap) GetWithDefault(key string, value int) int { this.mu.Lock() diff --git a/g/container/gmap/string_interface_map.go b/g/container/gmap/string_interface_map.go index 4dbb6c4ab..5e470f160 100644 --- a/g/container/gmap/string_interface_map.go +++ b/g/container/gmap/string_interface_map.go @@ -10,6 +10,7 @@ package gmap import ( "sync" "gitee.com/johng/gf/g/util/gconv" + "time" ) type StringInterfaceMap struct { @@ -82,27 +83,71 @@ func (this *StringInterfaceMap) GetWithDefault(key string, value interface{}) in } func (this *StringInterfaceMap) GetBool(key string) bool { - return gconv.Bool(this.Get(key)) + return gconv.Bool(this.Get(key)) } func (this *StringInterfaceMap) GetInt(key string) int { - return gconv.Int(this.Get(key)) + return gconv.Int(this.Get(key)) +} + +func (this *StringInterfaceMap) GetInt8(key string) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *StringInterfaceMap) GetInt16(key string) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *StringInterfaceMap) GetInt32(key string) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *StringInterfaceMap) GetInt64(key string) int64 { + return gconv.Int64(this.Get(key)) } func (this *StringInterfaceMap) GetUint (key string) uint { - return gconv.Uint(this.Get(key)) + return gconv.Uint(this.Get(key)) +} + +func (this *StringInterfaceMap) GetUint8 (key string) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *StringInterfaceMap) GetUint16 (key string) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *StringInterfaceMap) GetUint32 (key string) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *StringInterfaceMap) GetUint64 (key string) uint64 { + return gconv.Uint64(this.Get(key)) } func (this *StringInterfaceMap) GetFloat32 (key string) float32 { - return gconv.Float32(this.Get(key)) + return gconv.Float32(this.Get(key)) } func (this *StringInterfaceMap) GetFloat64 (key string) float64 { - return gconv.Float64(this.Get(key)) + return gconv.Float64(this.Get(key)) } func (this *StringInterfaceMap) GetString (key string) string { - return gconv.String(this.Get(key)) + return gconv.String(this.Get(key)) +} + +func (this *StringInterfaceMap) GetStrings (key string) []string { + return gconv.Strings(this.Get(key)) +} + +func (this *StringInterfaceMap) GetTime (key string, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *StringInterfaceMap) GetTimeDuration (key string) time.Duration { + return gconv.TimeDuration(this.Get(key)) } // 删除键值对 diff --git a/g/container/gmap/string_string_map.go b/g/container/gmap/string_string_map.go index 33bea9847..4c8d4262c 100644 --- a/g/container/gmap/string_string_map.go +++ b/g/container/gmap/string_string_map.go @@ -9,6 +9,8 @@ package gmap import ( "sync" + "gitee.com/johng/gf/g/util/gconv" + "time" ) type StringStringMap struct { @@ -68,6 +70,74 @@ func (this *StringStringMap) Get(key string) string { return val } +func (this *StringStringMap) GetBool(key string) bool { + return gconv.Bool(this.Get(key)) +} + +func (this *StringStringMap) GetInt(key string) int { + return gconv.Int(this.Get(key)) +} + +func (this *StringStringMap) GetInt8(key string) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *StringStringMap) GetInt16(key string) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *StringStringMap) GetInt32(key string) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *StringStringMap) GetInt64(key string) int64 { + return gconv.Int64(this.Get(key)) +} + +func (this *StringStringMap) GetUint (key string) uint { + return gconv.Uint(this.Get(key)) +} + +func (this *StringStringMap) GetUint8 (key string) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *StringStringMap) GetUint16 (key string) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *StringStringMap) GetUint32 (key string) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *StringStringMap) GetUint64 (key string) uint64 { + return gconv.Uint64(this.Get(key)) +} + +func (this *StringStringMap) GetFloat32 (key string) float32 { + return gconv.Float32(this.Get(key)) +} + +func (this *StringStringMap) GetFloat64 (key string) float64 { + return gconv.Float64(this.Get(key)) +} + +func (this *StringStringMap) GetString (key string) string { + return gconv.String(this.Get(key)) +} + +func (this *StringStringMap) GetStrings (key string) []string { + return gconv.Strings(this.Get(key)) +} + +func (this *StringStringMap) GetTime (key string, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *StringStringMap) GetTimeDuration (key string) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 获取键值,如果键值不存在则写入默认值 func (this *StringStringMap) GetWithDefault(key string, value string) string { this.mu.Lock() diff --git a/g/container/gmap/uint_interface_map.go b/g/container/gmap/uint_interface_map.go index d3d7fa6a5..e6e622bea 100644 --- a/g/container/gmap/uint_interface_map.go +++ b/g/container/gmap/uint_interface_map.go @@ -10,6 +10,7 @@ package gmap import ( "sync" "gitee.com/johng/gf/g/util/gconv" + "time" ) type UintInterfaceMap struct { @@ -79,7 +80,6 @@ func (this *UintInterfaceMap) GetWithDefault(key uint, value interface{}) interf this.mu.Unlock() return val } - func (this *UintInterfaceMap) GetBool(key uint) bool { return gconv.Bool(this.Get(key)) } @@ -88,10 +88,42 @@ func (this *UintInterfaceMap) GetInt(key uint) int { return gconv.Int(this.Get(key)) } +func (this *UintInterfaceMap) GetInt8(key uint) int8 { + return gconv.Int8(this.Get(key)) +} + +func (this *UintInterfaceMap) GetInt16(key uint) int16 { + return gconv.Int16(this.Get(key)) +} + +func (this *UintInterfaceMap) GetInt32(key uint) int32 { + return gconv.Int32(this.Get(key)) +} + +func (this *UintInterfaceMap) GetInt64(key uint) int64 { + return gconv.Int64(this.Get(key)) +} + func (this *UintInterfaceMap) GetUint (key uint) uint { return gconv.Uint(this.Get(key)) } +func (this *UintInterfaceMap) GetUint8 (key uint) uint8 { + return gconv.Uint8(this.Get(key)) +} + +func (this *UintInterfaceMap) GetUint16 (key uint) uint16 { + return gconv.Uint16(this.Get(key)) +} + +func (this *UintInterfaceMap) GetUint32 (key uint) uint32 { + return gconv.Uint32(this.Get(key)) +} + +func (this *UintInterfaceMap) GetUint64 (key uint) uint64 { + return gconv.Uint64(this.Get(key)) +} + func (this *UintInterfaceMap) GetFloat32 (key uint) float32 { return gconv.Float32(this.Get(key)) } @@ -104,6 +136,18 @@ func (this *UintInterfaceMap) GetString (key uint) string { return gconv.String(this.Get(key)) } +func (this *UintInterfaceMap) GetStrings (key uint) []string { + return gconv.Strings(this.Get(key)) +} + +func (this *UintInterfaceMap) GetTime (key uint, format...string) time.Time { + return gconv.Time(this.Get(key), format...) +} + +func (this *UintInterfaceMap) GetTimeDuration (key uint) time.Duration { + return gconv.TimeDuration(this.Get(key)) +} + // 删除键值对 func (this *UintInterfaceMap) Remove(key uint) { this.mu.Lock() diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 24dd51d50..1dad364db 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -21,6 +21,7 @@ import ( "gitee.com/johng/gf/g/encoding/gyaml" "gitee.com/johng/gf/g/encoding/gtoml" "gitee.com/johng/gf/g/util/gstr" + "time" ) const ( @@ -32,7 +33,7 @@ type Json struct { mu sync.RWMutex p *interface{} // 注意这是一个指针 c byte // 层级分隔符,默认为"." - vc bool // 是否执行分隔符冲突检测(默认为true,检测会比较影响检索效率) + vc bool // 是否执行分隔符冲突检测(默认为false,检测会比较影响检索效率) } // 将变量转换为Json对象进行处理,该变量至少应当是一个map或者array,否者转换没有意义 @@ -42,13 +43,13 @@ func New(value interface{}) *Json { return &Json{ p : &value, c : byte(gDEFAULT_SPLIT_CHAR), - vc : true , + vc : false , } case []interface{}: return &Json{ p : &value, c : byte(gDEFAULT_SPLIT_CHAR), - vc : true , + vc : false , } default: // 这里效率会比较低 @@ -57,7 +58,7 @@ func New(value interface{}) *Json { return &Json{ p : &v, c : byte(gDEFAULT_SPLIT_CHAR), - vc : true, + vc : false, } } } @@ -144,7 +145,8 @@ func (j *Json) SetSplitChar(char byte) { j.mu.Unlock() } -// 设置自定义的层级分隔符号 +// 设置是否执行层级冲突检查,当键名中存在层级符号时需要开启该特性,默认为关闭。 +// 开启比较耗性能,也不建议允许键名中存在分隔符,最好在应用端避免这种情况。 func (j *Json) SetViolenceCheck(check bool) { j.mu.Lock() j.vc = check @@ -205,6 +207,19 @@ func (j *Json) GetString(pattern string) string { return gconv.String(j.Get(pattern)) } +// 返回指定json中的strings(转换为[]string数组) +func (j *Json) GetStrings(pattern string) []string { + return gconv.Strings(j.Get(pattern)) +} + +func (j *Json) GetTime(pattern string, format ... string) time.Time { + return gconv.Time(j.Get(pattern), format...) +} + +func (j *Json) GetTimeDuration(pattern string) time.Duration { + return gconv.TimeDuration(j.Get(pattern)) +} + // 返回指定json中的bool(false:"", 0, false, off) func (j *Json) GetBool(pattern string) bool { return gconv.Bool(j.Get(pattern)) @@ -460,18 +475,22 @@ func (j *Json) setPointerWithValue(pointer *interface{}, key string, value inter return pointer } -// 根据约定字符串方式访问json解析数据,参数形如: "items.name.first", "list.0" -// 返回的结果类型的interface{},因此需要自己做类型转换 -// 如果找不到对应节点的数据,返回nil -func (j *Json) Get(pattern string) interface{} { +// 根据约定字符串方式访问json解析数据,参数形如: "items.name.first", "list.0"; 当pattern为空时,表示获取所有数据; +// 返回的结果类型的interface{},因此需要自己做类型转换; +// 如果找不到对应节点的数据,返回nil; +func (j *Json) Get(pattern...string) interface{} { j.mu.RLock() defer j.mu.RUnlock() + queryPattern := "" + if len(pattern) > 0 { + queryPattern = pattern[0] + } var result *interface{} if j.vc { - result = j.getPointerByPattern(pattern) + result = j.getPointerByPattern(queryPattern) } else { - result = j.getPointerByPatternWithoutSplitCharViolenceCheck(pattern) + result = j.getPointerByPatternWithoutSplitCharViolenceCheck(queryPattern) } if result != nil { return *result diff --git a/g/encoding/gparser/gparser.go b/g/encoding/gparser/gparser.go index a711ef466..ad73dd507 100644 --- a/g/encoding/gparser/gparser.go +++ b/g/encoding/gparser/gparser.go @@ -9,6 +9,7 @@ package gparser import ( "gitee.com/johng/gf/g/encoding/gjson" + "time" ) type Parser struct { @@ -74,6 +75,18 @@ func (p *Parser) GetString(pattern string) string { return p.json.GetString(pattern) } +func (p *Parser) GetStrings(pattern string) []string { + return p.json.GetStrings(pattern) +} + +func (p *Parser) GetTime(pattern string, format ... string) time.Time { + return p.json.GetTime(pattern, format...) +} + +func (p *Parser) GetTimeDuration(pattern string) time.Duration { + return p.json.GetTimeDuration(pattern) +} + // 返回指定json中的bool(false:"", 0, false, off) func (p *Parser) GetBool(pattern string) bool { return p.json.GetBool(pattern) @@ -138,11 +151,11 @@ func (p *Parser) Remove(pattern string) error { return p.json.Remove(pattern) } -// 根据约定字符串方式访问json解析数据,参数形如: "items.name.first", "list.0" -// 返回的结果类型的interface{},因此需要自己做类型转换 -// 如果找不到对应节点的数据,返回nil -func (p *Parser) Get(pattern string) interface{} { - return p.json.Get(pattern) +// 根据约定字符串方式访问json解析数据,参数形如: "items.name.first", "list.0"; 当pattern为空时,表示获取所有数据 +// 返回的结果类型的interface{},因此需要自己做类型转换; +// 如果找不到对应节点的数据,返回nil; +func (p *Parser) Get(pattern...string) interface{} { + return p.json.Get(pattern...) } // 转换为map[string]interface{}类型,如果转换失败,返回nil diff --git a/g/os/gcfg/gcfg.go b/g/os/gcfg/gcfg.go index 10652ac86..e5429fce9 100644 --- a/g/os/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -132,6 +132,13 @@ func (c *Config) GetString(pattern string, file...string) string { return "" } +func (c *Config) GetStrings(pattern string, file...string) []string { + if j := c.getJson(file...); j != nil { + return j.GetStrings(pattern) + } + return nil +} + // 返回指定json中的bool func (c *Config) GetBool(pattern string, file...string) bool { if j := c.getJson(file...); j != nil { From 59c0ee97e9f06af00b8b72ab01234cfed8d78ac9 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 1 Jul 2018 00:33:49 +0800 Subject: [PATCH 12/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgparser=E5=8C=85SetViol?= =?UTF-8?q?enceCheck=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/encoding/gparser/gparser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g/encoding/gparser/gparser.go b/g/encoding/gparser/gparser.go index ad73dd507..150243869 100644 --- a/g/encoding/gparser/gparser.go +++ b/g/encoding/gparser/gparser.go @@ -49,7 +49,7 @@ func (p *Parser) SetSplitChar(char byte) { // 设置自定义的层级分隔符号 func (p *Parser) SetViolenceCheck(check bool) { - p.SetViolenceCheck(check) + p.json.SetViolenceCheck(check) } // 将指定的json内容转换为指定结构返回,查找失败或者转换失败,目标对象转换为nil From b167c037842bb958ae20b3cb161aa34d0e9c0c4a Mon Sep 17 00:00:00 2001 From: John Date: Sun, 1 Jul 2018 00:38:35 +0800 Subject: [PATCH 13/18] =?UTF-8?q?gcfg=E5=8C=85=E5=A2=9E=E5=8A=A0SetViolenc?= =?UTF-8?q?eCheck=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/encoding/gjson/gjson.go | 2 +- g/encoding/gparser/gparser.go | 3 ++- g/os/gcfg/gcfg.go | 10 ++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 1dad364db..0e9920cff 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -33,7 +33,7 @@ type Json struct { mu sync.RWMutex p *interface{} // 注意这是一个指针 c byte // 层级分隔符,默认为"." - vc bool // 是否执行分隔符冲突检测(默认为false,检测会比较影响检索效率) + vc bool // 层级检索是否执行分隔符冲突检测(默认为false,检测会比较影响检索效率) } // 将变量转换为Json对象进行处理,该变量至少应当是一个map或者array,否者转换没有意义 diff --git a/g/encoding/gparser/gparser.go b/g/encoding/gparser/gparser.go index 150243869..2966448de 100644 --- a/g/encoding/gparser/gparser.go +++ b/g/encoding/gparser/gparser.go @@ -47,7 +47,8 @@ func (p *Parser) SetSplitChar(char byte) { p.json.SetSplitChar(char) } -// 设置自定义的层级分隔符号 +// 设置是否执行层级冲突检查,当键名中存在层级符号时需要开启该特性,默认为关闭。 +// 开启比较耗性能,也不建议允许键名中存在分隔符,最好在应用端避免这种情况。 func (p *Parser) SetViolenceCheck(check bool) { p.json.SetViolenceCheck(check) } diff --git a/g/os/gcfg/gcfg.go b/g/os/gcfg/gcfg.go index e5429fce9..36d3dd6dc 100644 --- a/g/os/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -26,6 +26,7 @@ type Config struct { paths *gspath.SPath // 搜索目录路径 jsons *gmap.StringInterfaceMap // 配置文件对象 closed *gtype.Bool // 是否已经被close + vc *gtype.Bool // 层级检索是否执行分隔符冲突检测(默认为false,检测会比较影响检索效率) } // 生成一个配置管理对象 @@ -41,6 +42,7 @@ func New(path string, file...string) *Config { paths : s, jsons : gmap.NewStringInterfaceMap(), closed : gtype.NewBool(), + vc : gtype.NewBool(), } } @@ -62,6 +64,13 @@ func (c *Config) SetPath(path string) error { return nil } +// 设置是否执行层级冲突检查,当键名中存在层级符号时需要开启该特性,默认为关闭。 +// 开启比较耗性能,也不建议允许键名中存在分隔符,最好在应用端避免这种情况。 +func (c *Config) SetViolenceCheck(check bool) { + c.vc.Set(check) + c.Reload() +} + // 添加配置管理器的配置文件搜索路径 func (c *Config) AddPath(path string) error { if err := c.paths.Add(path); err != nil { @@ -91,6 +100,7 @@ func (c *Config) getJson(file...string) *gjson.Json { return r.(*gjson.Json) } if j, err := gjson.Load(fpath); err == nil { + j.SetViolenceCheck(c.vc.Val()) c.addMonitor(fpath) c.jsons.Set(fpath, j) return j From 360e540cd0d70727fb70d84e9b6a34b4df857fe9 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 1 Jul 2018 09:42:42 +0800 Subject: [PATCH 14/18] =?UTF-8?q?=E5=8E=BB=E6=8E=89gmap=E4=B8=AD=E5=B8=B8?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E5=9F=BA=E6=9C=AC=E6=95=B0=E6=8D=AE=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=BD=AC=E6=8D=A2=E8=8E=B7=E5=8F=96=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/int_int_map.go | 66 ------------------- g/container/gmap/int_interface_map.go | 70 --------------------- g/container/gmap/int_string_map.go | 66 ------------------- g/container/gmap/interface_interface_map.go | 70 --------------------- g/container/gmap/string_int_map.go | 70 --------------------- g/container/gmap/string_interface_map.go | 70 --------------------- g/container/gmap/string_string_map.go | 70 --------------------- g/container/gmap/uint_interface_map.go | 69 -------------------- 8 files changed, 551 deletions(-) diff --git a/g/container/gmap/int_int_map.go b/g/container/gmap/int_int_map.go index a1f87951e..78785939a 100644 --- a/g/container/gmap/int_int_map.go +++ b/g/container/gmap/int_int_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type IntIntMap struct { @@ -70,70 +68,6 @@ func (this *IntIntMap) Get(key int) (int) { return val } -func (this *IntIntMap) GetBool(key int) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *IntIntMap) GetInt(key int) int { - return gconv.Int(this.Get(key)) -} - -func (this *IntIntMap) GetInt8(key int) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *IntIntMap) GetInt16(key int) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *IntIntMap) GetInt32(key int) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *IntIntMap) GetInt64(key int) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *IntIntMap) GetUint (key int) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *IntIntMap) GetUint8 (key int) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *IntIntMap) GetUint16 (key int) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *IntIntMap) GetUint32 (key int) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *IntIntMap) GetUint64 (key int) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *IntIntMap) GetFloat32 (key int) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *IntIntMap) GetFloat64 (key int) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *IntIntMap) GetString (key int) string { - return gconv.String(this.Get(key)) -} - -func (this *IntIntMap) GetTime (key int, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *IntIntMap) GetTimeDuration (key int) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 获取键值,如果键值不存在则写入默认值 func (this *IntIntMap) GetWithDefault(key int, value int) int { this.mu.Lock() diff --git a/g/container/gmap/int_interface_map.go b/g/container/gmap/int_interface_map.go index dbac2bd67..596d2fdb7 100644 --- a/g/container/gmap/int_interface_map.go +++ b/g/container/gmap/int_interface_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type IntInterfaceMap struct { @@ -82,74 +80,6 @@ func (this *IntInterfaceMap) GetWithDefault(key int, value interface{}) interfac return val } -func (this *IntInterfaceMap) GetBool(key int) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *IntInterfaceMap) GetInt(key int) int { - return gconv.Int(this.Get(key)) -} - -func (this *IntInterfaceMap) GetInt8(key int) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *IntInterfaceMap) GetInt16(key int) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *IntInterfaceMap) GetInt32(key int) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *IntInterfaceMap) GetInt64(key int) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *IntInterfaceMap) GetUint (key int) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *IntInterfaceMap) GetUint8 (key int) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *IntInterfaceMap) GetUint16 (key int) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *IntInterfaceMap) GetUint32 (key int) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *IntInterfaceMap) GetUint64 (key int) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *IntInterfaceMap) GetFloat32 (key int) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *IntInterfaceMap) GetFloat64 (key int) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *IntInterfaceMap) GetString (key int) string { - return gconv.String(this.Get(key)) -} - -func (this *IntInterfaceMap) GetStrings (key int) []string { - return gconv.Strings(this.Get(key)) -} - -func (this *IntInterfaceMap) GetTime (key int, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *IntInterfaceMap) GetTimeDuration (key int) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 删除键值对 func (this *IntInterfaceMap) Remove(key int) { this.mu.Lock() diff --git a/g/container/gmap/int_string_map.go b/g/container/gmap/int_string_map.go index 6cde82dc5..10b685691 100644 --- a/g/container/gmap/int_string_map.go +++ b/g/container/gmap/int_string_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type IntStringMap struct { @@ -70,70 +68,6 @@ func (this *IntStringMap) Get(key int) string { return val } -func (this *IntStringMap) GetBool(key int) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *IntStringMap) GetInt(key int) int { - return gconv.Int(this.Get(key)) -} - -func (this *IntStringMap) GetInt8(key int) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *IntStringMap) GetInt16(key int) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *IntStringMap) GetInt32(key int) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *IntStringMap) GetInt64(key int) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *IntStringMap) GetUint (key int) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *IntStringMap) GetUint8 (key int) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *IntStringMap) GetUint16 (key int) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *IntStringMap) GetUint32 (key int) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *IntStringMap) GetUint64 (key int) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *IntStringMap) GetFloat32 (key int) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *IntStringMap) GetFloat64 (key int) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *IntStringMap) GetString (key int) string { - return gconv.String(this.Get(key)) -} - -func (this *IntStringMap) GetTime (key int, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *IntStringMap) GetTimeDuration (key int) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 获取键值,如果键值不存在则写入默认值 func (this *IntStringMap) GetWithDefault(key int, value string) string { this.mu.Lock() diff --git a/g/container/gmap/interface_interface_map.go b/g/container/gmap/interface_interface_map.go index 437fcee49..38b843a97 100644 --- a/g/container/gmap/interface_interface_map.go +++ b/g/container/gmap/interface_interface_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type InterfaceInterfaceMap struct { @@ -82,74 +80,6 @@ func (this *InterfaceInterfaceMap) GetWithDefault(key interface{}, value interfa return val } -func (this *InterfaceInterfaceMap) GetBool(key interface{}) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetInt(key interface{}) int { - return gconv.Int(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetInt8(key interface{}) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetInt16(key interface{}) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetInt32(key interface{}) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetInt64(key interface{}) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetUint (key interface{}) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetUint8 (key interface{}) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetUint16 (key interface{}) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetUint32 (key interface{}) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetUint64 (key interface{}) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetFloat32 (key interface{}) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetFloat64 (key interface{}) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetString (key interface{}) string { - return gconv.String(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetStrings (key interface{}) []string { - return gconv.Strings(this.Get(key)) -} - -func (this *InterfaceInterfaceMap) GetTime (key interface{}, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *InterfaceInterfaceMap) GetTimeDuration (key interface{}) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 删除键值对 func (this *InterfaceInterfaceMap) Remove(key interface{}) { this.mu.Lock() diff --git a/g/container/gmap/string_int_map.go b/g/container/gmap/string_int_map.go index ce6dd035d..17487dfc2 100644 --- a/g/container/gmap/string_int_map.go +++ b/g/container/gmap/string_int_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type StringIntMap struct { @@ -70,74 +68,6 @@ func (this *StringIntMap) Get(key string) int { return val } -func (this *StringIntMap) GetBool(key string) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *StringIntMap) GetInt(key string) int { - return gconv.Int(this.Get(key)) -} - -func (this *StringIntMap) GetInt8(key string) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *StringIntMap) GetInt16(key string) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *StringIntMap) GetInt32(key string) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *StringIntMap) GetInt64(key string) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *StringIntMap) GetUint (key string) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *StringIntMap) GetUint8 (key string) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *StringIntMap) GetUint16 (key string) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *StringIntMap) GetUint32 (key string) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *StringIntMap) GetUint64 (key string) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *StringIntMap) GetFloat32 (key string) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *StringIntMap) GetFloat64 (key string) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *StringIntMap) GetString (key string) string { - return gconv.String(this.Get(key)) -} - -func (this *StringIntMap) GetStrings (key string) []string { - return gconv.Strings(this.Get(key)) -} - -func (this *StringIntMap) GetTime (key string, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *StringIntMap) GetTimeDuration (key string) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 获取键值,如果键值不存在则写入默认值 func (this *StringIntMap) GetWithDefault(key string, value int) int { this.mu.Lock() diff --git a/g/container/gmap/string_interface_map.go b/g/container/gmap/string_interface_map.go index 5e470f160..8143038f9 100644 --- a/g/container/gmap/string_interface_map.go +++ b/g/container/gmap/string_interface_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type StringInterfaceMap struct { @@ -82,74 +80,6 @@ func (this *StringInterfaceMap) GetWithDefault(key string, value interface{}) in return val } -func (this *StringInterfaceMap) GetBool(key string) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *StringInterfaceMap) GetInt(key string) int { - return gconv.Int(this.Get(key)) -} - -func (this *StringInterfaceMap) GetInt8(key string) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *StringInterfaceMap) GetInt16(key string) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *StringInterfaceMap) GetInt32(key string) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *StringInterfaceMap) GetInt64(key string) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *StringInterfaceMap) GetUint (key string) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *StringInterfaceMap) GetUint8 (key string) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *StringInterfaceMap) GetUint16 (key string) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *StringInterfaceMap) GetUint32 (key string) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *StringInterfaceMap) GetUint64 (key string) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *StringInterfaceMap) GetFloat32 (key string) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *StringInterfaceMap) GetFloat64 (key string) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *StringInterfaceMap) GetString (key string) string { - return gconv.String(this.Get(key)) -} - -func (this *StringInterfaceMap) GetStrings (key string) []string { - return gconv.Strings(this.Get(key)) -} - -func (this *StringInterfaceMap) GetTime (key string, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *StringInterfaceMap) GetTimeDuration (key string) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 删除键值对 func (this *StringInterfaceMap) Remove(key string) { this.mu.Lock() diff --git a/g/container/gmap/string_string_map.go b/g/container/gmap/string_string_map.go index 4c8d4262c..33bea9847 100644 --- a/g/container/gmap/string_string_map.go +++ b/g/container/gmap/string_string_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type StringStringMap struct { @@ -70,74 +68,6 @@ func (this *StringStringMap) Get(key string) string { return val } -func (this *StringStringMap) GetBool(key string) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *StringStringMap) GetInt(key string) int { - return gconv.Int(this.Get(key)) -} - -func (this *StringStringMap) GetInt8(key string) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *StringStringMap) GetInt16(key string) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *StringStringMap) GetInt32(key string) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *StringStringMap) GetInt64(key string) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *StringStringMap) GetUint (key string) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *StringStringMap) GetUint8 (key string) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *StringStringMap) GetUint16 (key string) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *StringStringMap) GetUint32 (key string) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *StringStringMap) GetUint64 (key string) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *StringStringMap) GetFloat32 (key string) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *StringStringMap) GetFloat64 (key string) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *StringStringMap) GetString (key string) string { - return gconv.String(this.Get(key)) -} - -func (this *StringStringMap) GetStrings (key string) []string { - return gconv.Strings(this.Get(key)) -} - -func (this *StringStringMap) GetTime (key string, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *StringStringMap) GetTimeDuration (key string) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} - // 获取键值,如果键值不存在则写入默认值 func (this *StringStringMap) GetWithDefault(key string, value string) string { this.mu.Lock() diff --git a/g/container/gmap/uint_interface_map.go b/g/container/gmap/uint_interface_map.go index e6e622bea..647b3e3bd 100644 --- a/g/container/gmap/uint_interface_map.go +++ b/g/container/gmap/uint_interface_map.go @@ -9,8 +9,6 @@ package gmap import ( "sync" - "gitee.com/johng/gf/g/util/gconv" - "time" ) type UintInterfaceMap struct { @@ -80,73 +78,6 @@ func (this *UintInterfaceMap) GetWithDefault(key uint, value interface{}) interf this.mu.Unlock() return val } -func (this *UintInterfaceMap) GetBool(key uint) bool { - return gconv.Bool(this.Get(key)) -} - -func (this *UintInterfaceMap) GetInt(key uint) int { - return gconv.Int(this.Get(key)) -} - -func (this *UintInterfaceMap) GetInt8(key uint) int8 { - return gconv.Int8(this.Get(key)) -} - -func (this *UintInterfaceMap) GetInt16(key uint) int16 { - return gconv.Int16(this.Get(key)) -} - -func (this *UintInterfaceMap) GetInt32(key uint) int32 { - return gconv.Int32(this.Get(key)) -} - -func (this *UintInterfaceMap) GetInt64(key uint) int64 { - return gconv.Int64(this.Get(key)) -} - -func (this *UintInterfaceMap) GetUint (key uint) uint { - return gconv.Uint(this.Get(key)) -} - -func (this *UintInterfaceMap) GetUint8 (key uint) uint8 { - return gconv.Uint8(this.Get(key)) -} - -func (this *UintInterfaceMap) GetUint16 (key uint) uint16 { - return gconv.Uint16(this.Get(key)) -} - -func (this *UintInterfaceMap) GetUint32 (key uint) uint32 { - return gconv.Uint32(this.Get(key)) -} - -func (this *UintInterfaceMap) GetUint64 (key uint) uint64 { - return gconv.Uint64(this.Get(key)) -} - -func (this *UintInterfaceMap) GetFloat32 (key uint) float32 { - return gconv.Float32(this.Get(key)) -} - -func (this *UintInterfaceMap) GetFloat64 (key uint) float64 { - return gconv.Float64(this.Get(key)) -} - -func (this *UintInterfaceMap) GetString (key uint) string { - return gconv.String(this.Get(key)) -} - -func (this *UintInterfaceMap) GetStrings (key uint) []string { - return gconv.Strings(this.Get(key)) -} - -func (this *UintInterfaceMap) GetTime (key uint, format...string) time.Time { - return gconv.Time(this.Get(key), format...) -} - -func (this *UintInterfaceMap) GetTimeDuration (key uint) time.Duration { - return gconv.TimeDuration(this.Get(key)) -} // 删除键值对 func (this *UintInterfaceMap) Remove(key uint) { From 69843c86dc106ab9d2cf6be7b2bda05c8a0f67bf Mon Sep 17 00:00:00 2001 From: John Date: Sun, 1 Jul 2018 18:56:50 +0800 Subject: [PATCH 15/18] =?UTF-8?q?=E6=94=B9=E8=BF=9Bgdb=E5=8C=85=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=E9=A2=84=E5=A4=84=E7=90=86=E5=8F=82=E6=95=B0=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E8=BD=AC=E6=8D=A2=E4=B8=BAstring=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/database/gdb/gdb_base.go | 9 ++++++--- g/database/gdb/gdb_transaction.go | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/g/database/gdb/gdb_base.go b/g/database/gdb/gdb_base.go index 48817a5b4..305d3b6c0 100644 --- a/g/database/gdb/gdb_base.go +++ b/g/database/gdb/gdb_base.go @@ -234,7 +234,7 @@ func (db *Db) insert(table string, data Map, option uint8) (sql.Result, error) { for k, v := range data { fields = append(fields, db.charl + k + db.charr) values = append(values, "?") - params = append(params, v) + params = append(params, gconv.String(v)) } operation := db.getInsertOperationByOption(option) updatestr := "" @@ -247,7 +247,10 @@ func (db *Db) insert(table string, data Map, option uint8) (sql.Result, error) { } return db.Exec( fmt.Sprintf("%s INTO %s%s%s(%s) VALUES(%s) %s", - operation, db.charl, table, db.charr, strings.Join(fields, ","), strings.Join(values, ","), updatestr), params... + operation, db.charl, table, db.charr, strings.Join(fields, ","), + strings.Join(values, ","), + updatestr), + params... ) } @@ -298,7 +301,7 @@ func (db *Db) batchInsert(table string, list List, batch int, option uint8) (sql // 构造批量写入数据格式(注意map的遍历是无序的) for i := 0; i < size; i++ { for _, k := range keys { - params = append(params, list[i][k]) + params = append(params, gconv.String(list[i][k])) } bvalues = append(bvalues, valueHolderStr) if len(bvalues) == batch { diff --git a/g/database/gdb/gdb_transaction.go b/g/database/gdb/gdb_transaction.go index 365bbb92c..9ded8f744 100644 --- a/g/database/gdb/gdb_transaction.go +++ b/g/database/gdb/gdb_transaction.go @@ -169,7 +169,7 @@ func (tx *Tx) insert(table string, data Map, option uint8) (sql.Result, error) { for k, v := range data { keys = append(keys, tx.db.charl + k + tx.db.charr) values = append(values, "?") - params = append(params, v) + params = append(params, gconv.String(v)) } operation := tx.db.getInsertOperationByOption(option) updatestr := "" @@ -182,7 +182,10 @@ func (tx *Tx) insert(table string, data Map, option uint8) (sql.Result, error) { } return tx.Exec( fmt.Sprintf("%s INTO %s%s%s(%s) VALUES(%s) %s", - operation, tx.db.charl, table, tx.db.charr, strings.Join(keys, ","), strings.Join(values, ","), updatestr), params... + operation, tx.db.charl, table, tx.db.charr, strings.Join(keys, ","), + strings.Join(values, ","), + updatestr), + params... ) } @@ -233,7 +236,7 @@ func (tx *Tx) batchInsert(table string, list List, batch int, option uint8) (sql // 构造批量写入数据格式(注意map的遍历是无序的) for i := 0; i < size; i++ { for _, k := range keys { - params = append(params, list[i][k]) + params = append(params, gconv.String(list[i][k])) } bvalues = append(bvalues, valueHolderStr) if len(bvalues) == batch { From dd6c3d1e291b6fd71fc7418852bce6c8356a0926 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 1 Jul 2018 19:13:25 +0800 Subject: [PATCH 16/18] =?UTF-8?q?=E6=94=B9=E8=BF=9Bgconv.String=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=BD=93=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E7=B1=BB=E5=9E=8B=E8=BF=9B=E8=A1=8C=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E8=BD=AC=E6=8D=A2=E6=97=B6=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8json.Marshal=E8=BF=9B=E8=A1=8C=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/util/gconv/gconv.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 98ab9a7e1..0b2bf8233 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -15,6 +15,7 @@ import ( "gitee.com/johng/gf/g/encoding/gbinary" "gitee.com/johng/gf/g/util/gstr" "gitee.com/johng/gf/g/os/gtime" + "github.com/gin-gonic/gin/json" ) // 将变量i转换为字符串指定的类型t @@ -117,7 +118,9 @@ func String(i interface{}) string { case string: return value case []byte: return string(value) default: - return fmt.Sprintf("%v", value) + // 默认使用json进行字符串转换 + jsonContent, _ := json.Marshal(value) + return string(jsonContent) } } From fda5c397b2d7121981bc4f646cfdcc59e39e5064 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 2 Jul 2018 14:08:15 +0800 Subject: [PATCH 17/18] =?UTF-8?q?=E5=82=BB=E9=80=BCIDE=EF=BC=8C=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=9C=A8gconv=E4=B8=AD=E5=8A=A0=E8=BD=BD=E4=BA=86gin?= =?UTF-8?q?=E5=8C=85=E7=9A=84json=E5=8C=85=EF=BC=8C=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E4=B8=BA=E6=A0=87=E5=87=86=E5=BA=93json?= =?UTF-8?q?=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO | 2 +- g/util/gconv/gconv.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index e37de6cb1..861470d72 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ Cookie&Session数据池化处理; ghttp.Client增加proxy特性; gtime增加对时区转换的封装,并简化失去转换时对类似+80500时区的支持; 改进gf-orm的where查询功能,参考thinkphp 里的where查询语法; - +gproc进程间通信增加分组特性,不同的进程见可以通过进程ID以及分组名称发送/获取消息; DONE: diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 0b2bf8233..45bc1fb30 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -12,10 +12,10 @@ import ( "fmt" "time" "strconv" - "gitee.com/johng/gf/g/encoding/gbinary" - "gitee.com/johng/gf/g/util/gstr" + "encoding/json" "gitee.com/johng/gf/g/os/gtime" - "github.com/gin-gonic/gin/json" + "gitee.com/johng/gf/g/util/gstr" + "gitee.com/johng/gf/g/encoding/gbinary" ) // 将变量i转换为字符串指定的类型t From 2c67a6ceb2d89727e32b465b7016759e70a1100f Mon Sep 17 00:00:00 2001 From: John Date: Mon, 2 Jul 2018 14:21:02 +0800 Subject: [PATCH 18/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E9=80=9A=E4=BF=A1=E4=B8=B4=E6=97=B6=E6=96=87=E4=BB=B6=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/os/gproc/gproc_comm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g/os/gproc/gproc_comm.go b/g/os/gproc/gproc_comm.go index 257981b65..a58efb822 100644 --- a/g/os/gproc/gproc_comm.go +++ b/g/os/gproc/gproc_comm.go @@ -50,7 +50,7 @@ func getCommFilePath(pid int) string { // 获取进程间通信目录地址 func getCommDirPath() string { - tempDir := os.Getenv("gproc.tempdir") + tempDir := os.Getenv(gPROC_TEMP_DIR_ENV_KEY) if tempDir == "" { tempDir = gfile.TempDir() }