gogf / gf Goto Github PK
View Code? Open in Web Editor NEWGoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
Home Page: https://goframe.org
License: MIT License
GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
Home Page: https://goframe.org
License: MIT License
httpclient,httpserver 虽然支持https,但是不能自定义tls的一些参数,比如信任ca,tls双向认证,证书校验,这些在很多安全要求高的领域都是必须的。其实给一个tls.Config设置的入口即可。另外HttpClient应该可以自定义设置tr,这样才能把HttpClient的方便性更好的发挥出来。
sms 包代码
package sms
type Message struct {
Mobile string `gvalid:"mobile@required#手机号必须"`
Type int `gvalid:"type@required#消息类型必须"`
Content string
TemplateId string `gvalid:"template_id@required-without:content#消息内容为空时,模板ID不能为空"`
Param string `gvalid:"param@required-with:template_id#模板ID存在时,参数不能为空"`
config map[string]interface{}
}
func NewMessage(mobile string, msgType int, content string, templateId string, param string) *Message {
c := g.Config()
_ = c.AddPath("config")
conf := c.GetMap("miaodi")
return &Message{
Mobile: mobile,
Type: msgType,
Content: content,
TemplateId: templateId,
Param: param,
config: conf,
}
}
main 包 代码
func main() {
message := sms.NewMessage("123",1,"456","333","1,3,9")
if e := gvalid.CheckStruct(message,nil); e != nil {
g.Dump(e.Maps())
}
}
报错
panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
goroutine 1 [running]:
reflect.valueInterface(0x9c5a00, 0xc00020a908, 0x1b5, 0x1, 0xc000204bc8, 0x0)
D:/Go/src/reflect/value.go:990 +0x1c6
reflect.Value.Interface(...)
D:/Go/src/reflect/value.go:979
github.com/gogf/gf/third/github.com/fatih/structs.(*Field).Value(...)
D:/gopath/pkg/mod/github.com/gogf/[email protected]/third/github.com/fatih/structs/field.go:31
github.com/gogf/gf/g/util/gvalid.CheckStruct(0x9e2ae0, 0xc00020a8c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6cd53)
D:/gopath/pkg/mod/github.com/gogf/[email protected]/g/util/gvalid/gvalid_check_struct.go:64 +0x32e
main.main()
D:/project/go/test/main.go:17 +0xb9
gproc.ShellExec 执行 nohup ./abc &, 推送后台执行命令会阻塞
用
gproc.ShellRun 执行就不会
func main() {
gudp.NewServer("0.0.0.0:10243", func(conn *gudp.Conn) {
defer conn.Close()
for {
if data, _ := conn.Recv(-1); len(data) > 0 {
fmt.Println("RemoteAddr",conn.RemoteAddr())
t := time.Now().Format("2006-01-02 15:04:05")
fmt.Println(t,"recv:",string(data))
conn.Send([]byte("got it"))
//res, _ := conn.SendRecv([]byte(t), -1)
//fmt.Println(string(res))
}
}
}).Run()
}
当客户端建立连接时,需要获取客户端信息,使用了自带的RemoteAddr方法,却拿不到任何信息
Go
are you using (go version
)?$ go version 1.11
GoFrame
are you using?1.57
yes
sqlDb, err = bs.db.Open(node)
if err != nil {
return nil
}
项目启动的时候,数据库连接超时,没有任何的记录,依然能正常启动,结果web接口也不报错,状态为0,导致很难排查线上问题。
应该给出日志,且项目终止启动;如果是运行的过程中db连接异常,应该给出日志,web接口应该给出500状态码
没有日志,接口状态码为0
package main
import (
"fmt"
"gitee.com/johng/gf/g/os/gfsnotify"
)
func main() {
err := gfsnotify.Add("C:/", func(event *gfsnotify.Event) {
if event.IsCreate() {
fmt.Println("创建文件 : ", event.Path)
}
if event.IsWrite() {
fmt.Println("写入文件 : ", event.Path)
}
if event.IsRemove() {
fmt.Println("删除文件 : ", event.Path)
}
if event.IsRename() {
fmt.Println("重命名文件 : ", event.Path)
}
if event.IsChmod() {
fmt.Println("修改权限 : ", event.Path)
}
})
if err != nil {
fmt.Println("遇到错误")
} else {
select {}
}
}
以上代码基于官网文档修改的,把打印直接显示到屏幕上。但是运行后,没有任何显示。换其他目录操作,也一样。
请问是否计划集成swagger文档功能?
beego、faygo等框架都很好的内嵌集成了swagger文档功能。
使用gparser.VarToXmlIndent将struct转为xml时,struct中定义的TAG不起作用,例如:
type User struct {
Name string `xml:"name" json:"name"`
Age int `xml:"bb" json:"dd" gconv:"aa"`
Addr string `xml:"cc"`
}
这个struct中Addr转为xml后标签本应为“cc”,但是实际结果为:
<user>
<Addr>kaldsj</Addr>
<aa>22</aa>
<name>sss</name>
</user>
测试代码如下:
package main
import (
"fmt"
"github.com/gogf/gf/g/encoding/gparser"
)
type User struct {
Name string `xml:"name" json:"name"`
Age int `xml:"bb" json:"dd" gconv:"aa"`
Addr string `xml:"cc"`
}
func main() {
user := User{
Name: "sss",
Age: 22,
Addr: "kaldsj",
}
xmlStr, err := gparser.VarToXmlIndent(user, "user")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(xmlStr))
}
Go
are you using (go version
)?$ go version 1.12
GoFrame
are you using?1.5.8
no
升级前配置文件按文档设置,未变动。
注释控制器内部代码或者不注释不影响报错。
生成路由表每次编译有可能不生成,或者生成index方法的,或者index和user方法的都生成。
怀疑bug,或者我路由注册方式有问题。不过升级前没出现过。
/router/router.go
func init() {
// 用户模块 路由注册 - 使用执行对象注册方式
s := g.Server()
s.BindController("/", new(controller.Index))
}
/app/controller/index.go
type Index struct {
gmvc.Controller
}
func (i *Index) Index() {
//...
}
func (i *Index) User() {
//...
}
如题。
github.com\gogf\[email protected]\g\net\greuseport\greuseport_windows.go:12:18: undefined: windows
不知道是不是特例。
Go
are you using (output of command: go version
)?$ go version go 1.12
GoFrame
are you using?v1.5.9
对
当 client 结束进程时,server 并没有接收到任何消息。
for {
data, err := conn.Recv(-1)
fmt.Println(string(data))
}
struct 查询有几个问题
package main
import (
"fmt"
"github.com/gogf/gf/g"
"github.com/gogf/gf/g/net/ghttp"
"github.com/gogf/gf/g/os/glog"
)
type UserController struct {
}
func (obj *UserController) Init(r *ghttp.Request) {
fmt.Println("Init")
Json(r, 0, "")
r.ExitAll()
}
func (c *UserController) Find(r *ghttp.Request) {
fmt.Println("Find")
Json(r, 0, "")
}
func Json(r *ghttp.Request, err int, msg string, data ...interface{}) {
responseData := interface{}(nil)
if len(data) > 0 {
responseData = data[0]
}
r.Response.WriteJson(g.Map{
"err": err,
"msg": msg,
"data": responseData,
})
r.Exit()
}
func main() {
s := g.Server()
s.BindHookHandlerByMap("/user/*", map[string]ghttp.HandlerFunc{
ghttp.HOOK_BEFORE_SERVE: func(r *ghttp.Request) {
glog.Println(ghttp.HOOK_BEFORE_SERVE)
Json(r, 0, "")
r.ExitHook()
},
ghttp.HOOK_AFTER_SERVE: func(r *ghttp.Request) { glog.Println(ghttp.HOOK_AFTER_SERVE) },
ghttp.HOOK_BEFORE_OUTPUT: func(r *ghttp.Request) { glog.Println(ghttp.HOOK_BEFORE_OUTPUT) },
ghttp.HOOK_AFTER_OUTPUT: func(r *ghttp.Request) { glog.Println(ghttp.HOOK_AFTER_OUTPUT) },
ghttp.HOOK_BEFORE_CLOSE: func(r *ghttp.Request) { glog.Println(ghttp.HOOK_BEFORE_CLOSE) },
ghttp.HOOK_AFTER_CLOSE: func(r *ghttp.Request) { glog.Println(ghttp.HOOK_AFTER_CLOSE) },
})
s.BindObject("/user", new(UserController))
s.SetPort(8888)
s.Run()
}
测试
curl http://localhost:8888/user/find
测试结果
2019-02-25 15:43:05.877 54835: http server started listening on [:8888]
2019-02-25 15:43:05.877 [DEBU] GF notices that you're in develop environment, so error logs are auto enabled to stdout.
SERVER | ADDRESS | DOMAIN | METHOD | P | ROUTE | HANDLER | HOOK
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/* | main.main.func6 | AfterClose
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/* | main.main.func4 | AfterOutput
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/* | main.main.func2 | AfterServe
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/* | main.main.func5 | BeforeClose
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/* | main.main.func3 | BeforeOutput
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/* | main.main.func1 | BeforeServe
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
default | :8888 | default | ALL | 2 | /user/find | main.(*UserController).Find |
|---------|---------|---------|--------|---|------------|-----------------------------|--------------|
2019-02-25 15:43:59.947 BeforeServe
Init
Find
2019-02-25 15:43:59.948 AfterServe
2019-02-25 15:43:59.948 BeforeOutput
2019-02-25 15:43:59.948 AfterOutput
2019-02-25 15:43:59.948 BeforeClose
2019-02-25 15:43:59.948 AfterClose
期望,我想做权限的拦截,采用 jwt 的集成,目前遇到两个问题
Go
and system type/arch are you using?GoFrame
are you using?Go
are you using (go version
)?go 1.12
$ go version
GoFrame
are you using?最新版本
不确定
我需要搭建标准WebSocket(SSL)服务,这个框架能实现吗?
@johng-cn 你好,我update了你最新的代码,使用的是postgresql数据库,时间字段的数据库类型是timestamp,数据库查询结果集转Time类型还是错误,我看了你最新的源代码,应该是时间类型的模板以及正则的使用有问题、我将我的这个时间类型的字段转String,都是类似这样的数据,“2018-02-09T20:33:18.814Z“,”2018-02-09T20:46:17.897Z”,另外该功能是否所有数据库都能支持,请将此功能在做一下完整的测试,谢谢。
Go
and system type/arch are you using?go 1.12 ubuntu18 64位
GoFrame
are you using?1.5.16
yes
a项目依赖gf,此项目为微服务的公共接口和model定义,只引用gf常见的工具;
b项目依赖gf,同时依赖b项目,但b项目启动的时候,db会初始化两次。
希望db以及其他类似组件不要强制初始化,因为一个项目可能只想引用gf的工具集
connections = gmap.New()
connections是一个保存了conn的地图
--------------------------------------------------
conn := connections.Get(parkingNo)
if conn == nil {
ResponseOK(c, "停车场未连接")
return
}
bytes := jsonutil.Marshal(request)
resBytes, err := conn.SendRecvWithTimeout(bytes, -1, 5*time.Second)
// 不会收到返回值,为什么
if err != nil {
ResponseOK(c, err.Error())
return
}
1.5.0
FROM loads/alpine:3.8
LABEL maintainer="[email protected]"
###############################################################################
# INSTALLATION
###############################################################################
ADD ./gf-app /bin/main
RUN chmod +x /bin/main
###############################################################################
# START
###############################################################################
CMD main
按照文档的那样写Dockerfile,因为没有指定CMD
命令的所在目录,这样会默认在根目录/
下。
这个时候代码配置如下配置文件目录
_ = c.AddPath("config")
_ = v.AddPath("template")
当程序启动的时候,就会添加/
和/config
、/template
三个目录到系统里面,但是程序还是会报找不到/config
下的文件,例如:
2019-02-22 17:21:46.711 [DEBU] [gview] SetPath: /
2019-02-22 17:21:46.712 [DEBU] [gcfg] SetPath: /
2019-02-22 17:21:46.712 [DEBU] [gcfg] AddPath: /config
2019-02-22 17:21:46.712 [DEBU] [gview] AddPath: /template
2019-02-22 17:21:46.713 [ERRO] [gcfg] cannot find config file "config.toml" in following paths:
1. /
2. /config
Backtrace:
1. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/os/gcfg/gcfg.go:84
2. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/os/gcfg/gcfg.go:137
3. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/os/gcfg/gcfg.go:174
4. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/frame/gins/gins.go:117
5. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/container/gmap/gmap_string_interface_map.go:110
6. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/container/gmap/gmap_string_interface_map.go:137
7. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/frame/gins/gins.go:115
8. /Users/chenjingyang/go/pkg/mod/github.com/gogf/[email protected]/g/g_object.go:53
9. /Users/chenjingyang/go/src/code-generator/boot/boot.go:30
具体问题还需要作者排查,但是可以通过指定CMD的工作目录,问题就得以解决
Dockerfile 修改为以下示例
FROM loads/alpine:3.8
LABEL maintainer="[email protected]"
###############################################################################
# INSTALLATION
###############################################################################
ADD ./gf-app /bin/main
RUN chmod +x /bin/main
RUN mkdir /root/config /root/template /root/public
COPY config/ /root/config
COPY template /root/template
###############################################################################
# START
###############################################################################
WORKDIR /root
CMD main
这只是一个示例,一般不会使用root权限来执行容器里面的程序
感谢作者的努力和无私奉献。
能否增加一个权限管理模块?
或者增加对 https://github.com/casbin/casbin 的支持?
比方说,一般情况下注册路由,
server.bindController("/web",new(WebController))
此时,/web 或者/web/ 指向 Index方法。
而批量注册路由的情况下,/web或者/web/为not found,必须/web/index才能正确解析
限制最大的goroutine数量(Pool.size)变大后对已经加入队列的jobs(queue队列任务)不会重新分配PoolWorker。
相反,pool.size字段变小需要PoolWorker回收后才能真正的限制到协和数量。
不知道上面的情况是否是设计的初衷?
被gf的路由注册、数据库record、自带很多常用的工具集等特点吸引过来,确实方便,花了几天时间打磨出一套快速开发平台,包括权限系统、代码生成的功能,目前也有几个系统在此平台运行。
由于系统涉及到高并发大流量的场景,我做了很多的压测,发现内存不断的增加,3种注册方式都测试过,函数注册、对象注册、控制器注册都试过,甚至函数注册逻辑只渲染一个简单的模板页面,最终结果都会导致内存不断增加,增加到2G之后我就没再做测试,等了数个小时之后,内存才降到200多M。
周末在家,我用gin实现了同样的功能,包括模板输出和json输出,在高并发的情况下,内存稳定在36M。
当然,gin用起来确实没有gf爽快,我希望作者给出内存不断增长的原因。
如题,有特定的场景:
server <-> client 互发消息时,可以正常监听到 EOF。
但是当使用 manage -> server -> client,manage 通过 server 中转消息给 client 后,client 再关闭,这时 server 就无法监听到中断的 EOF 了。
我上三段代码:
server.go
package main
import (
"fmt"
"github.com/gogf/gf/g/encoding/gjson"
"github.com/gogf/gf/g/net/gtcp"
"github.com/gogf/gf/g/os/glog"
"time"
)
var (
myClients = map[*gtcp.Conn]string{}
)
func main() {
gtcp.NewServer(":12345", func(conn *gtcp.Conn) {
defer conn.Close()
for {
data, err := conn.Recv(-1)
fmt.Println(string(data), err)
if len(data) > 0 {
if j, err := gjson.DecodeToJson(data); err != nil {
glog.Error(err)
} else {
operate := j.GetString("operate")
switch operate {
case "register":
uuid := j.GetString("uuid")
myClients[conn] = uuid
conn.Send(data)
break
case "anything":
if j, err := gjson.DecodeToJson([]byte("{}")); err != nil {
glog.Error(err)
} else {
j.Set("operate", "anything")
j.Set("result", true)
c, _ := j.ToJson()
if err := conn.Send(c); err != nil {
fmt.Println(err, "anything send error")
}
}
break
case "do_anything":
uuid := j.GetString("uuid")
if j, err := gjson.DecodeToJson([]byte("{}")); err != nil {
glog.Error(err)
} else {
j.Set("operate", "do_anything")
j.Set("timestamp", time.Now().Unix())
c, _ := j.ToJson()
for connect, uid := range myClients {
fmt.Println(uid == uuid,uid,"<>",uuid)
if uid == uuid {
isSend := connect.Send(c)
fmt.Println("send to " + uuid, isSend)
}
}
}
break
case "stop":
uuid := j.GetString("uuid")
for connect, uid := range myClients {
if uid == uuid {
connect.Close()
fmt.Println("close to " + uuid)
}
}
break
}
}
}
if err != nil {
fmt.Println(err, err.Error() == "EOF")
//关闭终端则移除设备
if err.Error() == "EOF" {
fmt.Println(myClients[conn], "exist", myClients)
if _, ok := myClients[conn]; ok {
delete(myClients, conn)
fmt.Println("remove")
}
}
break
}
}
}).Run()
}
client.go
package main
import (
"fmt"
"github.com/gogf/gf/g/encoding/gjson"
"github.com/gogf/gf/g/net/gtcp"
"github.com/gogf/gf/g/os/glog"
"time"
)
func main() {
message1 :=
`{
"operate": "register",
"uuid": "123456789"
}`
message2 :=
`{
"operate": "anything",
"content": "content"
}`
message := message1
for {
if conn, err := gtcp.NewPoolConn("127.0.0.1:12345"); err == nil {
if b, err := conn.SendRecv([]byte(message), -1); err == nil {
fmt.Println(string(b), conn.LocalAddr(), conn.RemoteAddr())
if j, err := gjson.DecodeToJson(b); err != nil {
glog.Error(err)
} else {
operate := j.GetString("operate")
if operate == "register" {
message = message2
}
}
} else {
glog.Error(err)
if err.Error() == "EOF" {
break
}
}
conn.Close()
} else {
glog.Error(err)
break
}
time.Sleep(time.Second * 5)
}
}
manage.go
package main
import (
"github.com/gogf/gf/g/net/gtcp"
"github.com/gogf/gf/g/os/glog"
)
func main() {
//"460010100000011", "460010100000012"
message3 := `{"operate": "do_anything", "uuid": "123456789"}`
message4 := `{"operate": "stop", "uuid": "123456789"}`
var message string
message = message4
message = message3
if conn, err := gtcp.NewConn("127.0.0.1:12345"); err == nil {
err := conn.Send([]byte(message))
if err != nil {
glog.Error(err)
}
conn.Close()
} else {
glog.Error(err)
}
}
管理端
go run manage.go
报错是
read tcp 127.0.0.1:12345->127.0.0.1:51803: read: connection reset by peer
read tcp 127.0.0.1:12345->127.0.0.1:51803: read: connection reset by peer false
控制器基类里面这样定义Shut
func (c *Controller) Shut()
,https://github.com/gogf/gf/blob/master/g/frame/gmvc/controller.go#L35
但是注册方法里面却这样转换,fshut = v.MethodByName("Shut").Interface().(func(*Request))
https://github.com/gogf/gf/blob/master/g/net/ghttp/ghttp_server_service_object.go#L40
导致继承基类的控制器都不能注册,会报pnaic错误,类型转换错误,
panic: interface conversion: interface {} is func(), not func(*ghttp.Request)
希望 gstr 中增加 ReplaceI 忽视大小写的替换方法, 和 ContainsI 配合使用
Go
and system type/arch are you using?GoFrame
are you using?问题:
32位服务器下,gconv.String()方法在转换int类型大值时,会溢出
64位服务器下,正常.
示例代码如下:
`
n1:= gconv.String(gtime.Now().Millisecond())
fmt.Println(n1)
`
gjson包希望增加 GetJsons 这样的方法,返回一个Json数组
`type DemoInfo struct {
Name string
Age string
}
l := map[interface{}][]DemoInfo{}
el := [...]DemoInfo{
{Name:"Bala", Age:"15"},
{Name:"CeCe", Age:"18"},
{Name:"ChenLo", Age:"28"},
{Name:"Bii", Age:"22"},
{Name:"Ann", Age:"23"},
{Name:"Bmx", Age:"88"},
}
fmt.Println(el)
for _,v := range el{
l[string(v.Name[0])] = append(l[string(v.Name[0])],v)
}
fmt.Println(l)
c.Response.WriteJson(l)`
数据库查询结果集转Time类型错误,请问查询出来的时间类型能转time.Time么?
我看到Value有个Time方法呀
难道要数据库里的是整型才行?
静态文件服务器,打开的文件是utf-8能正常显示,若文件编码是ANSI格式,打开后就是乱码。
如静态html文件,ansi格式保存:
meta http-equiv="Content-Type" content="text/html; charset=gb2312"
package main
import (
"github.com/gogf/gf/g"
)
func main(){
s := g.Server()
s.SetIndexFolder(true)
s.SetServerRoot("C:\ HTML版")
s.Run()
}
注:另外go内置的静态文件服务器也是上述情况(乱码)。
新增加方法希望能实现:获取最近执行的完整的sql语句字符串.
如下:
`
rs,_:=db.Table("cd_orderform").Where("title like '九寨%'").OrderBy("orderform0 desc").Limit(0,3).Select()
sqls:=db.GetLastSql()
fmt.Println(sqls) // print : select * from cd_orderform where title like '九寨%' order by orderform0 desc limit 0,3
`
这样在开发时,对排查问题,很有帮助。
看了一下gf感觉很不错,但有一点我觉得可以学习下faygo的参数自动绑定验证的功能,方便快捷,一个struct hander非常方便。。。
ajax 希望增加 Access-Control-Allow-Headers
的设置, 支持对Authorization的认证方式
我现在是这么做的
r.Response.Header().Set("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization")
package main
import (
"gitee.com/johng/gf/g/database/gdb"
"fmt"
)
var db *gdb.Db
func init() {
gdb.AddDefaultConfigNode(gdb.ConfigNode {
Host : "127.0.0.1",
Port : "3306",
User : "root",
Pass : "123456",
Name : "test",
Type : "mysql",
Role : "master",
Charset : "utf8",
})
var err error
db, err = gdb.Instance()
checkErr(err)
}
func main() {
query()
insert()
}
// 基本sql查询
func query() {
fmt.Println("query:")
list, err := db.GetAll("select * from user limit 2")
if err == nil {
fmt.Println(list)
} else {
fmt.Println(err)
}
fmt.Println()
}
// 数据写入
func insert() {
fmt.Println("insert:")
r, err := db.Insert("user", gdb.Map {
"name": "john",
})
if err == nil {
uid, _ := r.LastInsertId()
fmt.Println(uid)
} else {
fmt.Println(err)
}
fmt.Println()
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
输出如下:
query:
[map[email:[email protected] type:1 uid:1 name:take] map[uid:14 name:flume email:[email protected] type:1]]
insert:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0xf0 pc=0x60bb92]
goroutine 1 [running]:
gitee.com/johng/gf/g/database/gdb.(*Db).Exec(0xc04203e200, 0xc042064870, 0x21, 0xc042036c40, 0x1, 0x1, 0x21, 0x1, 0x4, 0x0)
D:/Goworks/src/gitee.com/johng/gf/g/database/gdb/gdb_base.go:51 +0x72
gitee.com/johng/gf/g/database/gdb.(*Db).insert(0xc04203e200, 0x68db07, 0x4, 0xc042064840, 0xc042072400, 0x0, 0x0, 0x0, 0x0)
D:/Goworks/src/gitee.com/johng/gf/g/database/gdb/gdb_base.go:205 +0xc34
gitee.com/johng/gf/g/database/gdb.(*Db).Insert(0xc04203e280, 0x68db07, 0x4, 0xc042064840, 0xc042064840, 0x0, 0x0, 0x0)
D:/Goworks/src/gitee.com/johng/gf/g/database/gdb/gdb_base.go:210 +0x64
main.insert()
D:/Goworks/src/edition/b.go:48 +0x1d4
main.main()
D:/Goworks/src/edition/b.go:28 +0x2c
exit status 2
user表结构:
CREATE TABLE `user` (
`uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '' COMMENT '昵称',
`email` varchar(60) NOT NULL DEFAULT '' COMMENT '邮箱',
`type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '订单',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
package main
import (
"fmt"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/os/gfile"
"gitee.com/johng/gf/g/os/gfsnotify"
"gitee.com/johng/gf/g/os/glog"
)
func main() {
// /home/john/temp 是一个目录,当然也可以指定文件
paths:=g.Config().GetFilePath()
fmt.Println("=====",paths)
path := "/ftpDic"
_, err := gfsnotify.Add(path, func(event *gfsnotify.Event) {
if event.IsCreate() {
glog.Println("创建文件 : ", event.Path)
}
if event.IsWrite() {
glog.Println("写入文件 : ", event.Path)
if gfile.Exists(event.Path) {
fmt.Printf("%s\n", gfile.GetContents(event.Path))
}
//gfile.GetContents()
}
if event.IsRemove() {
glog.Println("删除文件 : ", event.Path)
}
if event.IsRename() {
glog.Println("重命名文件 : ", event.Path)
}
if event.IsChmod() {
glog.Println("修改权限 : ", event.Path)
}
glog.Println(event)
})
// 移除对该path的监听
// gfsnotify.Remove(path)
if err != nil {
glog.Fatal(err)
} else {
select {}
}
}
在1.5.2版本中,不存在的路由,页面依然返回200状态码,自动注册的404无效;
经查,ghttp_server_handler.go文件中的一次commit,
if len(request.Response.Header()) == 0 &&
request.Response.Status == 0 &&
request.Response.BufferLength() == 0 {
request.Response.WriteStatus(http.StatusNotFound)
}
跟进上面的response,发现
// 创建请求处理对象
request := newRequest(s, r, w)
r := &Response {
Server : s,
ResponseWriter : ResponseWriter {
ResponseWriter : w,
Status : http.StatusOK,
buffer : bytes.NewBuffer(nil),
},
}
r.Writer = &r.ResponseWriter
return r
response状态码初始化为200,所以永远不会进入if方法,导致不会产生404错误,请作者看看我的分析是否正确
模版热更新有问题,多次修改html模版并刷新页面,会出现空白页面的情况
首先支持一下。
性能如何?和主流web框架来个benchmark比一下?
目前我知道可以通过Hook回调事件设置跨域
有没有配置参数全局设置呢?或者是针对特定路由设置
文档代码:
if tx, err := db.Begin(); err == nil {
r, err := tx.Table("user").Data(gdb.Map{"uid":1, "name": "john_1"}).Save()
tx.Commit()
fmt.Println(r, err)
}
在使用过程中多进行一条语句操作,事务就不生效了:
if tx, err := db.Begin(); err == nil {
r, err := tx.Table("user").Data(gdb.Map{"uid":1, "name": "john_1"}).Save()
rd, errd := tx.Table("user").Where("uid=?",2).Delete()
tx.Commit()
fmt.Println(r, err)
fmt.Println(rd, errd)
}
文档中也没有找到相关的介绍,不知道这是框架的机制还是我使用不正确造成的,还望大神回复一下。
是否能集成类似flyway那种数据库脚本管理的支持
建议路由添加分组功能
类似 gin router
s.group("/api")
现在手机号有16x和19x了
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.