mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
add iterate example for glist; improve variable name for ghttp.Server
This commit is contained in:
@ -10,10 +10,10 @@ func main() {
|
||||
// Push
|
||||
l.PushBack(1)
|
||||
l.PushBack(2)
|
||||
e0 := l.PushFront(0)
|
||||
e := l.PushFront(0)
|
||||
// Insert
|
||||
l.InsertBefore(e0, -1)
|
||||
l.InsertAfter(e0, "a")
|
||||
l.InsertBefore(e, -1)
|
||||
l.InsertAfter(e, "a")
|
||||
fmt.Println(l)
|
||||
// Pop
|
||||
fmt.Println(l.PopFront())
|
||||
|
||||
@ -1,10 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/glist"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(gtime.Timestamp())
|
||||
// concurrent-safe list.
|
||||
l := glist.NewFrom(garray.NewArrayRange(1, 10, 1).Slice(), true)
|
||||
// iterate reading from head.
|
||||
l.RLockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
fmt.Print(e.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
fmt.Println()
|
||||
// iterate reading from tail.
|
||||
l.RLockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Back(); i < length; i, e = i+1, e.Prev() {
|
||||
fmt.Print(e.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Println()
|
||||
|
||||
// iterate writing from head.
|
||||
l.LockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
if e.Value == 6 {
|
||||
e.Value = "M"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
fmt.Println(l)
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ package garray
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"math"
|
||||
"sort"
|
||||
@ -45,6 +46,21 @@ func NewArraySize(size int, cap int, safe ...bool) *Array {
|
||||
}
|
||||
}
|
||||
|
||||
// NewArrayRange creates and returns a array by a range from <start> to <end>
|
||||
// with step value <step>.
|
||||
func NewArrayRange(start, end, step int, safe ...bool) *Array {
|
||||
if step == 0 {
|
||||
panic(fmt.Sprintf(`invalid step value: %d`, step))
|
||||
}
|
||||
slice := make([]interface{}, (end-start+1)/step)
|
||||
index := 0
|
||||
for i := start; i <= end; i += step {
|
||||
slice[index] = i
|
||||
index++
|
||||
}
|
||||
return NewArrayFrom(slice, safe...)
|
||||
}
|
||||
|
||||
// See NewArrayFrom.
|
||||
func NewFrom(array []interface{}, safe ...bool) *Array {
|
||||
return NewArrayFrom(array, safe...)
|
||||
|
||||
@ -9,6 +9,7 @@ package garray
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
@ -39,6 +40,21 @@ func NewIntArraySize(size int, cap int, safe ...bool) *IntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// NewIntArrayRange creates and returns a array by a range from <start> to <end>
|
||||
// with step value <step>.
|
||||
func NewIntArrayRange(start, end, step int, safe ...bool) *IntArray {
|
||||
if step == 0 {
|
||||
panic(fmt.Sprintf(`invalid step value: %d`, step))
|
||||
}
|
||||
slice := make([]int, (end-start+1)/step)
|
||||
index := 0
|
||||
for i := start; i <= end; i += step {
|
||||
slice[index] = i
|
||||
index++
|
||||
}
|
||||
return NewIntArrayFrom(slice, safe...)
|
||||
}
|
||||
|
||||
// NewIntArrayFrom creates and returns an array with given slice <array>.
|
||||
// The parameter <safe> is used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
|
||||
@ -9,6 +9,7 @@ package garray
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"github.com/gogf/gf/util/gutil"
|
||||
"math"
|
||||
@ -50,6 +51,21 @@ func NewSortedArraySize(cap int, comparator func(a, b interface{}) int, safe ...
|
||||
}
|
||||
}
|
||||
|
||||
// NewSortedArrayRange creates and returns a array by a range from <start> to <end>
|
||||
// with step value <step>.
|
||||
func NewSortedArrayRange(start, end, step int, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
|
||||
if step == 0 {
|
||||
panic(fmt.Sprintf(`invalid step value: %d`, step))
|
||||
}
|
||||
slice := make([]interface{}, (end-start+1)/step)
|
||||
index := 0
|
||||
for i := start; i <= end; i += step {
|
||||
slice[index] = i
|
||||
index++
|
||||
}
|
||||
return NewSortedArrayFrom(slice, comparator, safe...)
|
||||
}
|
||||
|
||||
// NewSortedArrayFrom creates and returns an sorted array with given slice <array>.
|
||||
// The parameter <safe> is used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
|
||||
@ -9,6 +9,7 @@ package garray
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
@ -53,6 +54,21 @@ func NewSortedIntArraySize(cap int, safe ...bool) *SortedIntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// NewSortedIntArrayRange creates and returns a array by a range from <start> to <end>
|
||||
// with step value <step>.
|
||||
func NewSortedIntArrayRange(start, end, step int, safe ...bool) *SortedIntArray {
|
||||
if step == 0 {
|
||||
panic(fmt.Sprintf(`invalid step value: %d`, step))
|
||||
}
|
||||
slice := make([]int, (end-start+1)/step)
|
||||
index := 0
|
||||
for i := start; i <= end; i += step {
|
||||
slice[index] = i
|
||||
index++
|
||||
}
|
||||
return NewSortedIntArrayFrom(slice, safe...)
|
||||
}
|
||||
|
||||
// NewIntArrayFrom creates and returns an sorted array with given slice <array>.
|
||||
// The parameter <safe> is used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
|
||||
@ -7,12 +7,14 @@
|
||||
package glist_test
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/container/garray"
|
||||
|
||||
"github.com/gogf/gf/container/glist"
|
||||
)
|
||||
|
||||
func Example_basic() {
|
||||
func Example_Basic() {
|
||||
n := 10
|
||||
l := glist.New()
|
||||
for i := 0; i < n; i++ {
|
||||
@ -35,3 +37,48 @@ func Example_basic() {
|
||||
//0123456789
|
||||
//0
|
||||
}
|
||||
|
||||
func Example_Iterate() {
|
||||
// concurrent-safe list.
|
||||
l := glist.NewFrom(garray.NewArrayRange(1, 10, 1).Slice(), true)
|
||||
// iterate reading from head.
|
||||
l.RLockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
fmt.Print(e.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
fmt.Println()
|
||||
// iterate reading from tail.
|
||||
l.RLockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Back(); i < length; i, e = i+1, e.Prev() {
|
||||
fmt.Print(e.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Println()
|
||||
|
||||
// iterate writing from head.
|
||||
l.LockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
if e.Value == 6 {
|
||||
e.Value = "M"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
fmt.Println(l)
|
||||
|
||||
//output:
|
||||
//12345678910
|
||||
//10987654321
|
||||
//[1,2,3,4,5,"M",7,8,9,10]
|
||||
}
|
||||
|
||||
@ -73,6 +73,7 @@ type ServerConfig struct {
|
||||
PProfPattern string // PProf: PProf service pattern for router.
|
||||
FormParsingMemory int64 // Other: Max memory in bytes which can be used for parsing multimedia form.
|
||||
NameToUriType int // Other: Type for converting struct method name to URI when registering routes.
|
||||
RouteOverWrite bool // Other: Allow overwrite the route if duplicated.
|
||||
DumpRouterMap bool // Other: Whether automatically dump router map when server starts.
|
||||
Graceful bool // Other: Enable graceful reload feature for all servers of the process.
|
||||
}
|
||||
|
||||
@ -15,3 +15,7 @@ func (s *Server) SetRewriteMap(rewrites map[string]string) {
|
||||
s.config.Rewrites[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) SetRouteOverWrite(enabled bool) {
|
||||
s.config.RouteOverWrite = enabled
|
||||
}
|
||||
|
||||
@ -72,11 +72,13 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) {
|
||||
}
|
||||
// 注册地址记录及重复注册判断
|
||||
regKey := s.handlerKey(handler.hookName, method, uri, domain)
|
||||
switch handler.itemType {
|
||||
case gHANDLER_TYPE_HANDLER, gHANDLER_TYPE_OBJECT, gHANDLER_TYPE_CONTROLLER:
|
||||
if item, ok := s.routesMap[regKey]; ok {
|
||||
glog.Fatalf(`duplicated route registry "%s", already registered at %s`, pattern, item[0].file)
|
||||
return
|
||||
if !s.config.RouteOverWrite {
|
||||
switch handler.itemType {
|
||||
case gHANDLER_TYPE_HANDLER, gHANDLER_TYPE_OBJECT, gHANDLER_TYPE_CONTROLLER:
|
||||
if item, ok := s.routesMap[regKey]; ok {
|
||||
glog.Fatalf(`duplicated route registry "%s", already registered at %s`, pattern, item[0].file)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// 注册的路由信息对象
|
||||
@ -263,8 +265,8 @@ func (s *Server) compareRouterPriority(newItem *handlerItem, oldItem *handlerIte
|
||||
return true
|
||||
}
|
||||
|
||||
// 最后新的规则比旧的规则优先级低
|
||||
return false
|
||||
// 最后新的规则比旧的规则优先级高(路由覆盖)
|
||||
return true
|
||||
}
|
||||
|
||||
// 将pattern(不带method和domain)解析成正则表达式匹配以及对应的query字符串
|
||||
|
||||
@ -53,7 +53,7 @@ func (s *Server) doBindController(pattern string, controller Controller, method
|
||||
// 当pattern中的method为all时,去掉该method,以便于后续方法判断
|
||||
domain, method, path, err := s.parsePattern(pattern)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
glog.Fatal(err)
|
||||
return
|
||||
}
|
||||
if strings.EqualFold(method, gDEFAULT_METHOD) {
|
||||
@ -63,15 +63,15 @@ func (s *Server) doBindController(pattern string, controller Controller, method
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(controller)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
pkgPath := t.Elem().PkgPath()
|
||||
pkgName := gfile.Basename(pkgPath)
|
||||
structName := t.Elem().Name()
|
||||
for i := 0; i < v.NumMethod(); i++ {
|
||||
mname := t.Method(i).Name
|
||||
if methodMap != nil && !methodMap[mname] {
|
||||
methodName := t.Method(i).Name
|
||||
if methodMap != nil && !methodMap[methodName] {
|
||||
continue
|
||||
}
|
||||
if mname == "Init" || mname == "Shut" || mname == "Exit" {
|
||||
if methodName == "Init" || methodName == "Shut" || methodName == "Exit" {
|
||||
continue
|
||||
}
|
||||
ctlName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "")
|
||||
@ -82,20 +82,20 @@ func (s *Server) doBindController(pattern string, controller Controller, method
|
||||
if len(methodMap) > 0 {
|
||||
// 指定的方法名称注册,那么需要使用错误提示
|
||||
glog.Errorf(`invalid route method: %s.%s.%s defined as "%s", but "func()" is required for controller registry`,
|
||||
pkgPath, ctlName, mname, v.Method(i).Type().String())
|
||||
pkgPath, ctlName, methodName, v.Method(i).Type().String())
|
||||
} else {
|
||||
// 否则只是Debug提示
|
||||
glog.Debugf(`ignore route method: %s.%s.%s defined as "%s", no match "func()"`,
|
||||
pkgPath, ctlName, mname, v.Method(i).Type().String())
|
||||
pkgPath, ctlName, methodName, v.Method(i).Type().String())
|
||||
}
|
||||
continue
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, true)
|
||||
key := s.mergeBuildInNameToPattern(pattern, structName, methodName, true)
|
||||
m[key] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, methodName),
|
||||
itemType: gHANDLER_TYPE_CONTROLLER,
|
||||
ctrlInfo: &handlerController{
|
||||
name: mname,
|
||||
name: methodName,
|
||||
reflect: v.Elem().Type(),
|
||||
},
|
||||
middleware: middleware,
|
||||
@ -104,17 +104,17 @@ func (s *Server) doBindController(pattern string, controller Controller, method
|
||||
// 例如: pattern为/user, 那么会同时注册/user及/user/index,
|
||||
// 这里处理新增/user路由绑定。
|
||||
// 注意,当pattern带有内置变量时,不会自动加该路由。
|
||||
if strings.EqualFold(mname, "Index") && !gregex.IsMatchString(`\{\.\w+\}`, pattern) {
|
||||
if strings.EqualFold(methodName, "Index") && !gregex.IsMatchString(`\{\.\w+\}`, pattern) {
|
||||
p := gstr.PosRI(key, "/index")
|
||||
k := key[0:p] + key[p+6:]
|
||||
if len(k) == 0 || k[0] == '@' {
|
||||
k = "/" + k
|
||||
}
|
||||
m[k] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, methodName),
|
||||
itemType: gHANDLER_TYPE_CONTROLLER,
|
||||
ctrlInfo: &handlerController{
|
||||
name: mname,
|
||||
name: methodName,
|
||||
reflect: v.Elem().Type(),
|
||||
},
|
||||
middleware: middleware,
|
||||
@ -128,11 +128,11 @@ func (s *Server) doBindControllerMethod(pattern string, controller Controller, m
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(controller)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
mname := strings.TrimSpace(method)
|
||||
fval := v.MethodByName(mname)
|
||||
if !fval.IsValid() {
|
||||
glog.Error("invalid method name:" + mname)
|
||||
structName := t.Elem().Name()
|
||||
methodName := strings.TrimSpace(method)
|
||||
methodValue := v.MethodByName(methodName)
|
||||
if !methodValue.IsValid() {
|
||||
glog.Fatal("invalid method name: " + methodName)
|
||||
return
|
||||
}
|
||||
pkgPath := t.Elem().PkgPath()
|
||||
@ -141,17 +141,17 @@ func (s *Server) doBindControllerMethod(pattern string, controller Controller, m
|
||||
if ctlName[0] == '*' {
|
||||
ctlName = fmt.Sprintf(`(%s)`, ctlName)
|
||||
}
|
||||
if _, ok := fval.Interface().(func()); !ok {
|
||||
if _, ok := methodValue.Interface().(func()); !ok {
|
||||
glog.Errorf(`invalid route method: %s.%s.%s defined as "%s", but "func()" is required for controller registry`,
|
||||
pkgPath, ctlName, mname, fval.Type().String())
|
||||
pkgPath, ctlName, methodName, methodValue.Type().String())
|
||||
return
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, false)
|
||||
key := s.mergeBuildInNameToPattern(pattern, structName, methodName, false)
|
||||
m[key] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, methodName),
|
||||
itemType: gHANDLER_TYPE_CONTROLLER,
|
||||
ctrlInfo: &handlerController{
|
||||
name: mname,
|
||||
name: methodName,
|
||||
reflect: v.Elem().Type(),
|
||||
},
|
||||
middleware: middleware,
|
||||
@ -164,13 +164,12 @@ func (s *Server) doBindControllerRest(pattern string, controller Controller, mid
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(controller)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
pkgPath := t.Elem().PkgPath()
|
||||
structName := t.Elem().Name()
|
||||
// 如果存在与HttpMethod对应名字的方法,那么绑定这些方法
|
||||
for i := 0; i < v.NumMethod(); i++ {
|
||||
mname := t.Method(i).Name
|
||||
method := strings.ToUpper(mname)
|
||||
if _, ok := methodsMap[method]; !ok {
|
||||
methodName := t.Method(i).Name
|
||||
if _, ok := methodsMap[strings.ToUpper(methodName)]; !ok {
|
||||
continue
|
||||
}
|
||||
pkgName := gfile.Basename(pkgPath)
|
||||
@ -180,15 +179,15 @@ func (s *Server) doBindControllerRest(pattern string, controller Controller, mid
|
||||
}
|
||||
if _, ok := v.Method(i).Interface().(func()); !ok {
|
||||
glog.Errorf(`invalid route method: %s.%s.%s defined as "%s", but "func()" is required for controller registry`,
|
||||
pkgPath, ctlName, mname, v.Method(i).Type().String())
|
||||
pkgPath, ctlName, methodName, v.Method(i).Type().String())
|
||||
return
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(mname+":"+pattern, sname, mname, false)
|
||||
key := s.mergeBuildInNameToPattern(methodName+":"+pattern, structName, methodName, false)
|
||||
m[key] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, methodName),
|
||||
itemType: gHANDLER_TYPE_CONTROLLER,
|
||||
ctrlInfo: &handlerController{
|
||||
name: mname,
|
||||
name: methodName,
|
||||
reflect: v.Elem().Type(),
|
||||
},
|
||||
middleware: middleware,
|
||||
|
||||
@ -51,19 +51,18 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
|
||||
// 当pattern中的method为all时,去掉该method,以便于后续方法判断
|
||||
domain, method, path, err := s.parsePattern(pattern)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
glog.Fatal(err)
|
||||
return
|
||||
}
|
||||
if strings.EqualFold(method, gDEFAULT_METHOD) {
|
||||
pattern = s.serveHandlerKey("", path, domain)
|
||||
}
|
||||
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(object)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
initFunc := (func(*Request))(nil)
|
||||
shutFunc := (func(*Request))(nil)
|
||||
structName := t.Elem().Name()
|
||||
if v.MethodByName("Init").IsValid() {
|
||||
initFunc = v.MethodByName("Init").Interface().(func(*Request))
|
||||
}
|
||||
@ -73,11 +72,11 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
|
||||
pkgPath := t.Elem().PkgPath()
|
||||
pkgName := gfile.Basename(pkgPath)
|
||||
for i := 0; i < v.NumMethod(); i++ {
|
||||
mname := t.Method(i).Name
|
||||
if methodMap != nil && !methodMap[mname] {
|
||||
methodName := t.Method(i).Name
|
||||
if methodMap != nil && !methodMap[methodName] {
|
||||
continue
|
||||
}
|
||||
if mname == "Init" || mname == "Shut" {
|
||||
if methodName == "Init" || methodName == "Shut" {
|
||||
continue
|
||||
}
|
||||
objName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "")
|
||||
@ -89,17 +88,17 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
|
||||
if len(methodMap) > 0 {
|
||||
// 指定的方法名称注册,那么需要使用错误提示
|
||||
glog.Errorf(`invalid route method: %s.%s.%s defined as "%s", but "func(*ghttp.Request)" is required for object registry`,
|
||||
pkgPath, objName, mname, v.Method(i).Type().String())
|
||||
pkgPath, objName, methodName, v.Method(i).Type().String())
|
||||
} else {
|
||||
// 否则只是Debug提示
|
||||
glog.Debugf(`ignore route method: %s.%s.%s defined as "%s", no match "func(*ghttp.Request)"`,
|
||||
pkgPath, objName, mname, v.Method(i).Type().String())
|
||||
pkgPath, objName, methodName, v.Method(i).Type().String())
|
||||
}
|
||||
continue
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, true)
|
||||
key := s.mergeBuildInNameToPattern(pattern, structName, methodName, true)
|
||||
m[key] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, methodName),
|
||||
itemType: gHANDLER_TYPE_OBJECT,
|
||||
itemFunc: itemFunc,
|
||||
initFunc: initFunc,
|
||||
@ -108,14 +107,14 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
|
||||
}
|
||||
// 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI。
|
||||
// 注意,当pattern带有内置变量时,不会自动加该路由。
|
||||
if strings.EqualFold(mname, "Index") && !gregex.IsMatchString(`\{\.\w+\}`, pattern) {
|
||||
if strings.EqualFold(methodName, "Index") && !gregex.IsMatchString(`\{\.\w+\}`, pattern) {
|
||||
p := gstr.PosRI(key, "/index")
|
||||
k := key[0:p] + key[p+6:]
|
||||
if len(k) == 0 || k[0] == '@' {
|
||||
k = "/" + k
|
||||
}
|
||||
m[k] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, methodName),
|
||||
itemType: gHANDLER_TYPE_OBJECT,
|
||||
itemFunc: itemFunc,
|
||||
initFunc: initFunc,
|
||||
@ -133,11 +132,11 @@ func (s *Server) doBindObjectMethod(pattern string, object interface{}, method s
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(object)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
mname := strings.TrimSpace(method)
|
||||
fval := v.MethodByName(mname)
|
||||
if !fval.IsValid() {
|
||||
glog.Error("invalid method name:" + mname)
|
||||
structName := t.Elem().Name()
|
||||
methodName := strings.TrimSpace(method)
|
||||
methodValue := v.MethodByName(methodName)
|
||||
if !methodValue.IsValid() {
|
||||
glog.Fatal("invalid method name: " + methodName)
|
||||
return
|
||||
}
|
||||
initFunc := (func(*Request))(nil)
|
||||
@ -154,15 +153,15 @@ func (s *Server) doBindObjectMethod(pattern string, object interface{}, method s
|
||||
if objName[0] == '*' {
|
||||
objName = fmt.Sprintf(`(%s)`, objName)
|
||||
}
|
||||
itemFunc, ok := fval.Interface().(func(*Request))
|
||||
itemFunc, ok := methodValue.Interface().(func(*Request))
|
||||
if !ok {
|
||||
glog.Errorf(`invalid route method: %s.%s.%s defined as "%s", but "func(*ghttp.Request)" is required for object registry`,
|
||||
pkgPath, objName, mname, fval.Type().String())
|
||||
pkgPath, objName, methodName, methodValue.Type().String())
|
||||
return
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, false)
|
||||
key := s.mergeBuildInNameToPattern(pattern, structName, methodName, false)
|
||||
m[key] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, methodName),
|
||||
itemType: gHANDLER_TYPE_OBJECT,
|
||||
itemFunc: itemFunc,
|
||||
initFunc: initFunc,
|
||||
@ -177,9 +176,9 @@ func (s *Server) doBindObjectRest(pattern string, object interface{}, middleware
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(object)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
initFunc := (func(*Request))(nil)
|
||||
shutFunc := (func(*Request))(nil)
|
||||
structName := t.Elem().Name()
|
||||
if v.MethodByName("Init").IsValid() {
|
||||
initFunc = v.MethodByName("Init").Interface().(func(*Request))
|
||||
}
|
||||
@ -188,9 +187,8 @@ func (s *Server) doBindObjectRest(pattern string, object interface{}, middleware
|
||||
}
|
||||
pkgPath := t.Elem().PkgPath()
|
||||
for i := 0; i < v.NumMethod(); i++ {
|
||||
mname := t.Method(i).Name
|
||||
method := strings.ToUpper(mname)
|
||||
if _, ok := methodsMap[method]; !ok {
|
||||
methodName := t.Method(i).Name
|
||||
if _, ok := methodsMap[strings.ToUpper(methodName)]; !ok {
|
||||
continue
|
||||
}
|
||||
pkgName := gfile.Basename(pkgPath)
|
||||
@ -201,12 +199,12 @@ func (s *Server) doBindObjectRest(pattern string, object interface{}, middleware
|
||||
itemFunc, ok := v.Method(i).Interface().(func(*Request))
|
||||
if !ok {
|
||||
glog.Errorf(`invalid route method: %s.%s.%s defined as "%s", but "func(*ghttp.Request)" is required for object registry`,
|
||||
pkgPath, objName, mname, v.Method(i).Type().String())
|
||||
pkgPath, objName, methodName, v.Method(i).Type().String())
|
||||
continue
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(mname+":"+pattern, sname, mname, false)
|
||||
key := s.mergeBuildInNameToPattern(methodName+":"+pattern, structName, methodName, false)
|
||||
m[key] = &handlerItem{
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, mname),
|
||||
itemName: fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, methodName),
|
||||
itemType: gHANDLER_TYPE_OBJECT,
|
||||
itemFunc: itemFunc,
|
||||
initFunc: initFunc,
|
||||
|
||||
Reference in New Issue
Block a user