改进gconv功能,完善gconv示例,README updates

This commit is contained in:
John 2018-04-15 10:30:59 +08:00
parent d0e999ff7b
commit 15c5d5b93b
13 changed files with 227 additions and 107 deletions

View File

@ -11,7 +11,7 @@
## 介绍
gf(Go Frame)是一款为Web服务及网络服务开发设计的模块化、低耦合、轻量级、高性能的Go语言开发框架。
实现了通用的HTTP/TCP/UDP Server并提供了Web服务开发的系列核心组件
包括MVC、Cookie、Session、模板引擎、路由控制、配置管理、数据校验、数据库操作(ORM)等等,
包括MVC、Cookie、Session、服务注册、路由控制、配置管理、模板引擎、数据校验、数据库操作(ORM)等等,
并且提供了数十个实用开发模块包括缓存模块、日志模块、JSON模块、命令行模块、二进制模块、环境变量模块、并发安全容器、Goroutine池等等。
gf是开源的免费的基于MIT协议进行分发开源项目地址(gitee与github仓库保持实时同步)
@ -28,6 +28,48 @@ gf是开源的免费的基于MIT协议进行分发开源项目地址(gi
1. 丰富详尽的框架文档及专业的技术支持/讨论群,易于使用及维护;
1. 更多特点请查阅框架手册( http://gf.johng.cn )
## 文档
* [框架介绍](http://gf.johng.cn/494364)
* [加入团队](http://gf.johng.cn/512841)
* [Web服务开发](http://gf.johng.cn/494647)
* [开始使用](http://gf.johng.cn/494366)
* [开发模式](http://gf.johng.cn/494367)
* [服务注册](http://gf.johng.cn/494368)
* [路由控制](http://gf.johng.cn/49437)
* [Cookie](http://gf.johng.cn/494372)
* [Session](http://gf.johng.cn/494373)
* [输入输出](http://gf.johng.cn/494374)
* [配置管理](http://gf.johng.cn/494376)
* [单例管理](http://gf.johng.cn/494377)
* [数据校验](http://gf.johng.cn/494378)
* [模板引擎](http://gf.johng.cn/494379)
* [数据库ORM](http://gf.johng.cn/494380)
* [网络服务开发](http://gf.johng.cn/494648)
* [TCPServer](http://gf.johng.cn/494382)
* [UDPServer](http://gf.johng.cn/494383)
* [功能模块设计](http://gf.johng.cn/494384)
* [缓存模块](http://gf.johng.cn/494385)
* [日志模块](http://gf.johng.cn/494386)
* [时间模块](http://gf.johng.cn/494387)
* [JSON模块](http://gf.johng.cn/494388)
* [命令行模块](http://gf.johng.cn/494389)
* [二进制模块](http://gf.johng.cn/500342)
* [HTTP客户端](http://gf.johng.cn/499674)
* [Goroutine池](http://gf.johng.cn/504458)
* [数据编码解析](http://gf.johng.cn/511393)
* [环境变量模块](http://gf.johng.cn/494390)
* [文件管理模块](http://gf.johng.cn/494391)
* [并发安全容器](http://gf.johng.cn/494392)
* [通用编码模块](http://gf.johng.cn/494393)
* [其他模块介绍](http://gf.johng.cn/494394)
## 贡献
gf是开源的、免费的软件这意味着任何人都可以为其开发和进步贡献力量。
gf的项目源代码目前同时托管在 Gitee 和 Github 平台上,您可以选择您喜欢的平台来 fork 项目和合并你的贡献,
两个平台的仓库将会保持即时的同步。我们非常欢迎有更多的朋友加入到gf框架的开发中来
您为gf所做出的任何贡献都将会被记录到gf的史册中。
## 安装
```
go get -u gitee.com/johng/gf
@ -176,7 +218,7 @@ go get -u gitee.com/johng/gf
r.Response.Write(r.Get("name"))
r.Response.Write(r.Get("action"))
})
s.BindHandler("/:name/:any", func(r *ghttp.Request){
s.BindHandler("/:name/*any", func(r *ghttp.Request){
r.Response.Write(r.Get("name"))
r.Response.Write(r.Get("any"))
})
@ -301,41 +343,8 @@ go get -u gitee.com/johng/gf
```
## 文档
* [框架介绍](http://gf.johng.cn/494364)
* [加入团队](http://gf.johng.cn/512841)
* [Web服务开发](http://gf.johng.cn/494647)
* [WebServer](http://gf.johng.cn/494366)
* [MVC模式](http://gf.johng.cn/494367)
* [服务注册](http://gf.johng.cn/494368)
* [Cookie](http://gf.johng.cn/494372)
* [Session](http://gf.johng.cn/494373)
* [输入输出](http://gf.johng.cn/494374)
* [路由控制](http://gf.johng.cn/49437)
* [配置管理](http://gf.johng.cn/494376)
* [单例管理](http://gf.johng.cn/494377)
* [数据校验](http://gf.johng.cn/494378)
* [模板引擎](http://gf.johng.cn/494379)
* [数据库ORM](http://gf.johng.cn/494380)
* [网络服务开发](http://gf.johng.cn/494648)
* [TCPServer](http://gf.johng.cn/494382)
* [UDPServer](http://gf.johng.cn/494383)
* [功能模块设计](http://gf.johng.cn/494384)
* [缓存模块](http://gf.johng.cn/494385)
* [日志模块](http://gf.johng.cn/494386)
* [时间模块](http://gf.johng.cn/494387)
* [JSON模块](http://gf.johng.cn/494388)
* [命令行模块](http://gf.johng.cn/494389)
* [二进制模块](http://gf.johng.cn/500342)
* [HTTP客户端](http://gf.johng.cn/499674)
* [Goroutine池](http://gf.johng.cn/504458)
* [数据编码解析](http://gf.johng.cn/511393)
* [环境变量模块](http://gf.johng.cn/494390)
* [文件管理模块](http://gf.johng.cn/494391)
* [并发安全容器](http://gf.johng.cn/494392)
* [通用编码模块](http://gf.johng.cn/494393)
* [其他模块介绍](http://gf.johng.cn/494394)
...
更多特性及示例请查看官方开发文档:[gf.johng.cn](http://gf.johng.cn)
## 贡献
gf是开源的、免费的软件这意味着任何人都可以为其开发和进步贡献力量。gf的项目源代码目前同时托管在 Gitee 和 Github 平台上,您可以选择您喜欢的平台来 fork 项目和合并你的贡献两个平台的仓库将会保持即时的同步。我们非常欢迎有更多的朋友加入到gf框架的开发中来您为gf所做出的任何贡献都将会被记录到gf的史册中。

View File

@ -295,12 +295,12 @@ func (db *Db) BatchSave(table string, list List, batch int) (sql.Result, error)
func (db *Db) Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) {
var params []interface{}
var updates string
switch data.(type) {
switch value := data.(type) {
case string:
updates = data.(string)
updates = value
case Map:
var keys []string
for k, v := range data.(Map) {
for k, v := range value {
keys = append(keys, fmt.Sprintf("%s%s%s=?", db.charl, k, db.charr))
params = append(params, v)
}

View File

@ -232,12 +232,12 @@ func (tx *Tx) BatchSave(table string, list List, batch int) (sql.Result, error)
func (tx *Tx) Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) {
var params []interface{}
var updates string
switch data.(type) {
switch value := data.(type) {
case string:
updates = data.(string)
updates = value
case Map:
var keys []string
for k, v := range data.(Map) {
for k, v := range value {
keys = append(keys, fmt.Sprintf("%s%s%s=?", tx.db.charl, k, tx.db.charr))
params = append(params, v)
}

View File

@ -22,12 +22,26 @@ type Response struct {
}
// 返回信息任何变量自动转换为bytes
func (r *Response) Write(content interface{}) {
func (r *Response) Write(content ... interface{}) {
if len(content) == 0 {
return
}
r.bufmu.Lock()
r.buffer = append(r.buffer, gconv.Bytes(content)...)
for _, v := range content {
r.buffer = append(r.buffer, gconv.Bytes(v)...)
}
r.bufmu.Unlock()
}
// 返回信息,末尾增加换行标识符"\n"
func (r *Response) Writeln(content ... interface{}) {
if len(content) == 0 {
return
}
content = append(content, "\n")
r.Write(content...)
}
// 返回JSON
func (r *Response) WriteJson(content interface{}) error {
if b, err := gparser.VarToJson(content); err != nil {

View File

@ -33,6 +33,8 @@ const (
type Server struct {
hmmu sync.RWMutex // handler互斥锁
hhmu sync.RWMutex // hooks互斥锁
hmcmu sync.RWMutex // handlerCache互斥锁
hhcmu sync.RWMutex // hooksCache互斥锁
name string // 服务名称,方便识别
server http.Server // 底层http server对象
config ServerConfig // 配置对象
@ -135,4 +137,28 @@ func (s *Server) Run() error {
}
s.status = 1
return nil
}
// 清空当前的handlerCache
func (s *Server) clearHandlerCache() {
// 只有在运行时才会生效
if s.status != 1 {
return
}
s.hmcmu.Lock()
defer s.hmcmu.Unlock()
s.handlerCache.Close()
s.handlerCache = gcache.New()
}
// 清空当前的hooksCache
func (s *Server) clearHooksCache() {
// 只有在运行时才会生效
if s.status != 1 {
return
}
s.hhcmu.Lock()
defer s.hhcmu.Unlock()
s.hooksCache.Close()
s.hooksCache = gcache.New()
}

View File

@ -32,6 +32,7 @@ func (s *Server) setHookHandler(pattern string, hook string, item *HandlerItem)
s.hhmu.Lock()
defer s.hhmu.Unlock()
defer s.clearHooksCache()
if _, ok := s.hooksTree[domain]; !ok {
s.hooksTree[domain] = make(map[string]interface{})
}
@ -86,6 +87,9 @@ func (s *Server) setHookHandler(pattern string, hook string, item *HandlerItem)
// 事件回调 - 检索动态路由规则
// 并按照指定hook回调函数的优先级及注册顺序进行调用
func (s *Server) callHookHandler(r *Request, hook string) {
s.hhcmu.RLock()
defer s.hhcmu.RUnlock()
var hookItems []*hookCacheItem
cacheKey := hook + "^" + r.URL.Path
if v := s.hooksCache.Get(cacheKey); v == nil {

View File

@ -23,6 +23,9 @@ type handlerCacheItem struct {
// 查询请求处理方法
// 这里有个锁机制,可以并发读,但是不能并发写
func (s *Server) getHandler(r *Request) *HandlerItem {
s.hmcmu.RLock()
defer s.hmcmu.RUnlock()
var handlerItem *handlerCacheItem
if v := s.handlerCache.Get(r.URL.Path); v == nil {
handlerItem = s.searchHandler(r)
@ -72,6 +75,7 @@ func (s *Server) setHandler(pattern string, item *HandlerItem) error {
// 静态注册
s.hmmu.Lock()
defer s.hmmu.Unlock()
defer s.clearHandlerCache()
if method == gDEFAULT_METHOD {
for v, _ := range s.methodsMap {
s.handlerMap[s.handlerKey(domain, v, uri)] = item

View File

@ -10,6 +10,7 @@ package gconv
import (
"fmt"
"strconv"
"gitee.com/johng/gf/g/encoding/gbinary"
)
@ -29,10 +30,22 @@ func String(i interface{}) string {
if i == nil {
return ""
}
if r, ok := i.(string); ok {
return r
} else {
return string(Bytes(i))
switch value := i.(type) {
case int: return strconv.Itoa(value)
case int8: return strconv.Itoa(int(value))
case int16: return strconv.Itoa(int(value))
case int32: return strconv.Itoa(int(value))
case int64: return strconv.Itoa(int(value))
case uint: return strconv.FormatUint(uint64(value), 10)
case uint8: return strconv.FormatUint(uint64(value), 10)
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 bool: return strconv.FormatBool(value)
case string: return value
case []byte: return string(value)
default:
return fmt.Sprintf("%v", value)
}
}
@ -70,10 +83,26 @@ func Int(i interface{}) int {
if i == nil {
return 0
}
if v, ok := i.(int); ok {
return v
switch value := i.(type) {
case int: return value
case int8: return int(value)
case int16: return int(value)
case int32: return int(value)
case int64: return int(value)
case uint: return int(value)
case uint8: return int(value)
case uint16: return int(value)
case uint32: return int(value)
case uint64: return int(value)
case bool:
if value {
return 1
}
return 0
default:
v, _ := strconv.Atoi(String(value))
return v
}
return gbinary.DecodeToInt(Bytes(i))
}
func Int8(i interface{}) int8 {
@ -83,7 +112,7 @@ func Int8(i interface{}) int8 {
if v, ok := i.(int8); ok {
return v
}
return gbinary.DecodeToInt8(Bytes(i))
return int8(Int(i))
}
func Int16(i interface{}) int16 {
@ -93,7 +122,7 @@ func Int16(i interface{}) int16 {
if v, ok := i.(int16); ok {
return v
}
return gbinary.DecodeToInt16(Bytes(i))
return int16(Int(i))
}
func Int32(i interface{}) int32 {
@ -103,7 +132,7 @@ func Int32(i interface{}) int32 {
if v, ok := i.(int32); ok {
return v
}
return gbinary.DecodeToInt32(Bytes(i))
return int32(Int(i))
}
func Int64(i interface{}) int64 {
@ -113,17 +142,33 @@ func Int64(i interface{}) int64 {
if v, ok := i.(int64); ok {
return v
}
return gbinary.DecodeToInt64(Bytes(i))
return int64(Int(i))
}
func Uint(i interface{}) uint {
if i == nil {
return 0
}
if v, ok := i.(uint); ok {
return v
switch value := i.(type) {
case int: return uint(value)
case int8: return uint(value)
case int16: return uint(value)
case int32: return uint(value)
case int64: return uint(value)
case uint: return value
case uint8: return uint(value)
case uint16: return uint(value)
case uint32: return uint(value)
case uint64: return uint(value)
case bool:
if value {
return 1
}
return 0
default:
v, _ := strconv.ParseUint(String(value), 10, 64)
return uint(v)
}
return gbinary.DecodeToUint(Bytes(i))
}
func Uint8(i interface{}) uint8 {
@ -133,7 +178,7 @@ func Uint8(i interface{}) uint8 {
if v, ok := i.(uint8); ok {
return v
}
return gbinary.DecodeToUint8(Bytes(i))
return uint8(Uint(i))
}
func Uint16(i interface{}) uint16 {
@ -143,7 +188,7 @@ func Uint16(i interface{}) uint16 {
if v, ok := i.(uint16); ok {
return v
}
return gbinary.DecodeToUint16(Bytes(i))
return uint16(Uint(i))
}
func Uint32(i interface{}) uint32 {
@ -153,7 +198,7 @@ func Uint32(i interface{}) uint32 {
if v, ok := i.(uint32); ok {
return v
}
return gbinary.DecodeToUint32(Bytes(i))
return uint32(Uint(i))
}
func Uint64(i interface{}) uint64 {
@ -163,7 +208,7 @@ func Uint64(i interface{}) uint64 {
if v, ok := i.(uint64); ok {
return v
}
return gbinary.DecodeToUint64(Bytes(i))
return uint64(Uint(i))
}
func Float32 (i interface{}) float32 {
@ -173,7 +218,8 @@ func Float32 (i interface{}) float32 {
if v, ok := i.(float32); ok {
return v
}
return gbinary.DecodeToFloat32(Bytes(i))
v, _ := strconv.ParseFloat(String(i), 32)
return float32(v)
}
func Float64 (i interface{}) float64 {
@ -183,5 +229,7 @@ func Float64 (i interface{}) float64 {
if v, ok := i.(float64); ok {
return v
}
return gbinary.DecodeToFloat64(Bytes(i))
v, _ := strconv.ParseFloat(String(i), 32)
return v
}

View File

@ -424,11 +424,11 @@ func Check(val interface{}, rules string, msgs interface{}, params...map[string]
// 自定义错误消息处理
list := make([]string, 0)
cmsgs := make(map[string]string)
switch msgs.(type) {
switch value := msgs.(type) {
case map[string]string:
cmsgs = msgs.(map[string]string)
cmsgs = value
case string:
list = strings.Split(msgs.(string), "|")
list = strings.Split(value, "|")
}
items := strings.Split(strings.TrimSpace(rules), "|")
for index := 0; index < len(items); {

View File

@ -1,29 +1,12 @@
package main
import (
"gitee.com/johng/gf/g/net/ghttp"
)
import "gitee.com/johng/gf/g/net/ghttp"
func main() {
ghttp.GetServer().BindHandler("/", func(r *ghttp.Request) {
//r.Response.RedirectTo("http://www.baidu.com/")
r.Response.Write("哈喽世界!")
//r.Response.WriteStatus(302)
s := ghttp.GetServer()
s.BindHandler("/", func(r *ghttp.Request){
r.Response.Writeln("哈喽世界!")
})
//ghttp.GetServer().BindHandler("/:name/*any", func(r *ghttp.Request) {
// r.Response.Write("any")
// r.Response.Write(r.Get("name"))
// r.Response.Write(r.Get("any"))
//})
////ghttp.GetServer().BindHandler("/:name/action", func(r *ghttp.Request) {
//// r.Response.Write(r.Get("name"))
////})
//ghttp.GetServer().BindHandler("/:name/:action/:aaa", func(r *ghttp.Request) {
// r.Response.Write("name")
// r.Response.Write(r.Get("name"))
// r.Response.Write(r.Get("action"))
//})
ghttp.GetServer().SetPort(10000)
ghttp.GetServer().Run()
s.SetPort(8199)
s.Run()
}

View File

@ -2,10 +2,22 @@ package main
import "gitee.com/johng/gf/g/net/ghttp"
func main () {
ghttp.GetServer().BindHandler("/router/*name", func(r *ghttp.Request) {
r.Response.Write(r.Get("name"))
func main() {
s := ghttp.GetServer()
s.BindHandler("/:name", func(r *ghttp.Request){
r.Response.Writeln("pattern: /:name match")
r.Response.Writeln(r.Get("name"))
})
ghttp.GetServer().SetPort(10000)
ghttp.GetServer().Run()
s.BindHandler("/:name/:action", func(r *ghttp.Request){
r.Response.Writeln("pattern: /:name/:action match")
r.Response.Writeln(r.Get("name"))
r.Response.Writeln(r.Get("action"))
})
s.BindHandler("/:name/*any", func(r *ghttp.Request){
r.Response.Writeln("pattern: /:name/*any match")
r.Response.Writeln(r.Get("name"))
r.Response.Writeln(r.Get("any"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -2,16 +2,10 @@ package main
import (
"fmt"
"gitee.com/johng/gf/g/util/gconv"
)
type T struct{
name string
}
func main() {
var i interface{} = T{"john"}
switch v := i.(type) {
case T:
default:
fmt.Println(v)
}
fmt.Println(gconv.Uint("123"))
}

26
geg/util/gconv.go Normal file
View File

@ -0,0 +1,26 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g/util/gconv"
)
func main() {
i := 123
fmt.Printf("%10s %v\n", "Int:", gconv.Int(i))
fmt.Printf("%10s %v\n", "Int8:", gconv.Int8(i))
fmt.Printf("%10s %v\n", "Int16:", gconv.Int16(i))
fmt.Printf("%10s %v\n", "Int32:", gconv.Int32(i))
fmt.Printf("%10s %v\n", "Int64:", gconv.Int64(i))
fmt.Printf("%10s %v\n", "Uint:", gconv.Uint(i))
fmt.Printf("%10s %v\n", "Uint8:", gconv.Uint8(i))
fmt.Printf("%10s %v\n", "Uint16:", gconv.Uint16(i))
fmt.Printf("%10s %v\n", "Uint32:", gconv.Uint32(i))
fmt.Printf("%10s %v\n", "Uint64:", gconv.Uint64(i))
fmt.Printf("%10s %v\n", "Float32:", gconv.Float32(i))
fmt.Printf("%10s %v\n", "Float64:", gconv.Float64(i))
fmt.Printf("%10s %v\n", "Bool:", gconv.Bool(i))
fmt.Printf("%10s %v\n", "Bytes:", gconv.Bytes(i))
fmt.Printf("%10s %v\n", "String:", gconv.String(i))
fmt.Printf("%10s %v\n", "Strings:", gconv.Strings(i))
}