Compare commits

..

76 Commits

Author SHA1 Message Date
c07c4d7217 version updates 2020-01-16 21:26:34 +08:00
b867b2a0bc add return parameter name for function Cas of gtype;improve Response.Redirect* functions by adding optional parameter code 2020-01-16 21:04:28 +08:00
872d674182 fix issue in database 'time' type support in package gdb 2020-01-15 21:23:40 +08:00
4682abafdf fix concurrent issue in gdb.Model.Count 2020-01-15 10:38:02 +08:00
b7d194cf52 improva gcmd.Parser/gres 2020-01-15 09:36:58 +08:00
edf2366296 improve gzip feature for gcompress; add gzip compression for package gres 2020-01-15 00:15:56 +08:00
22af5be71f rename parameter name for gipv4.Ip2Long/Long2Ip 2020-01-13 14:50:06 +08:00
f662ff8051 add pprof unit testing case for ghttp; reame updates 2020-01-12 22:26:07 +08:00
8c51121b3b version updates 2020-01-11 10:40:13 +08:00
e9a0805801 add function Schema for gdb 2020-01-10 23:48:19 +08:00
afadbc6621 improve genv.Remove/gproc.Kill 2020-01-10 22:32:07 +08:00
ca546fc30b why the goland auto removed my genv import? 2020-01-10 09:39:54 +08:00
7c7c168c3d improve gproc.SearchBinary 2020-01-09 23:05:03 +08:00
16f0bb96db improve strict parsing feature for gcmd 2020-01-08 23:06:01 +08:00
33a899d32e add As function for gdb.Model; improve string quote handling for gdb 2020-01-08 21:24:33 +08:00
f3a208f02f fix issue in router value retrieving for ghttp.Request 2020-01-08 20:00:42 +08:00
81fd3d06bb make parser default unstrict for gcmd 2020-01-08 19:30:56 +08:00
9227139cf8 add schema changing feature for gdb 2020-01-07 22:14:32 +08:00
f2190e50b2 improve unit testing for gdb 2020-01-06 20:43:59 +08:00
c4537b4753 improve ghttp.Client.Get 2020-01-06 17:57:07 +08:00
167d58490b Merge pull request #455 from gnever/191229_gfile_add_readline_mst
Add ReadLines and ReadByteLines read file content line by line
2020-01-06 17:52:41 +08:00
d36aceb9f1 Merge pull request #463 from sth4me/patch-1
fix mysql debug time
2020-01-06 17:51:33 +08:00
eb31922124 fix mysql debug time
调试模式时间格式改为毫秒,原来是微秒.
2020-01-06 10:28:34 +08:00
bec9f5a847 add buildin function 'concat' for gview 2020-01-05 19:55:17 +08:00
506552c3a9 example codes update; donator updates 2020-01-04 17:19:50 +08:00
2bacc77224 improve JSON/XML parsing feature for ghttp.Request 2020-01-04 15:35:21 +08:00
bc53f265af improve gconv.Map/String 2020-01-03 20:23:10 +08:00
344f232c36 add Timestamp*Str functions for gtime; improve unit testing cases for gfile 2020-01-02 21:29:06 +08:00
27b677b0c0 improve Map converting feature for gconv; improve package gproc for local shell searching; improve JSON/XML response for ghttp.Response 2020-01-02 19:45:41 +08:00
a5a0e381bd add more examples for ghttp.Server 2020-01-01 16:45:43 +08:00
d528d7f5ab donator updates 2020-01-01 15:24:10 +08:00
821c71bd8d improve parameter parsing feature for ghttp.Request 2020-01-01 15:20:03 +08:00
604a10400d improve parameter parsing feature for ghttp.Request 2020-01-01 14:57:57 +08:00
9219471f67 improve parameter parsing feature for ghttp.Request 2020-01-01 14:26:00 +08:00
fe5d2e5685 improve parameter parsing feature for ghttp.Request 2020-01-01 14:18:00 +08:00
0a89daa513 add more unit testing cases for gdb.TX 2019-12-31 16:02:18 +08:00
d6e6ddf996 Add gfile.ReadLines and gfile.ReadByteLines read file content line by line 2019-12-29 19:24:56 +08:00
5dbda8aedc fix issue in unit testing codes in gfile 2019-12-29 14:15:17 +08:00
134e4cf28f improve gfile.CopyDir function; add Model function for gdb.Model 2019-12-28 13:55:05 +08:00
56a85abef7 add AutoEncode feature for gview 2019-12-26 11:03:59 +08:00
80c6ceaf26 fix issue 437 2019-12-25 21:22:06 +08:00
a10f428715 add Iterator* functions for garray; add ReplaceDir*/ReplaceFile* functions for gfile; remove gfile.Replace/ReplaceFunc functions 2019-12-25 20:56:39 +08:00
597f7468e9 fix issue in prefix feature for method operations of gdb 2019-12-23 23:14:54 +08:00
5db8851213 comment update for gtype 2019-12-20 23:23:50 +08:00
1d53d760d8 README/DONATOR update; improve ghttp 2019-12-19 15:38:34 +08:00
922e720d63 improve gdb/ghttp/gins; fix issue in gstr 2019-12-19 15:14:05 +08:00
50018773b7 add iterate example for glist; improve variable name for ghttp.Server 2019-12-18 19:45:46 +08:00
df99036d41 add iterate example for glist; improve variable name for ghttp.Server 2019-12-18 19:44:40 +08:00
ae0fa888f0 add iterate example for glist; improve variable name for ghttp.Server 2019-12-18 19:40:07 +08:00
18892fb66d add iterate example for glist; improve variable name for ghttp.Server 2019-12-18 19:37:07 +08:00
5f2be10563 improve gdb/gtime 2019-12-17 21:06:34 +08:00
a5a88222a6 gofmt 2019-12-16 22:51:17 +08:00
4facdd5c9e gofmt 2019-12-16 21:22:42 +08:00
76bc9bd385 improve gdb.Model 2019-12-16 21:00:16 +08:00
364452f3bb improve gdb.Model 2019-12-16 20:50:27 +08:00
4996755f11 improve gcmd.Scan* 2019-12-14 22:48:53 +08:00
e33230a88f add package gbuild 2019-12-14 17:01:27 +08:00
951ce46932 fix data race issue in unit testing cases for gtcp 2019-12-13 18:50:54 +08:00
795c7395e6 fix data race issue in unit testing cases for gtcp 2019-12-13 17:40:29 +08:00
27cf47bcd3 improve table prefix and quote feature for gdb 2019-12-13 15:25:49 +08:00
58a25c6f61 fix data race issue in unit testing of gtcp 2019-12-13 14:26:07 +08:00
2d754f80b1 fix data race issue in unit testing of gtcp 2019-12-13 13:43:28 +08:00
f4e8fbe767 fix issue in unit testing codes for gtcp 2019-12-13 08:57:39 +08:00
458318d374 improve prefix and word quote feature for gdb; merge develop 2019-12-12 23:54:07 +08:00
e3f54e1353 improve tag and field retrieving feature for internal/structs; comment update for gdb 2019-12-12 23:38:46 +08:00
4374996073 add some Must* functions for gparser/gjson/gmd5/gsha1/gbase64 2019-12-12 11:40:23 +08:00
87295ef1fe improve process communication feature for gproc; add more slice converting functions for gconv 2019-12-11 21:22:41 +08:00
81d4082b6a fix issue in Retry.Interval type changed for gtcp 2019-12-11 14:54:38 +08:00
d7e19bc3f3 improve package feature for gtcp 2019-12-11 14:50:25 +08:00
34ef0ea792 add prefix feature for gdb 2019-12-10 21:14:15 +08:00
2804834540 rename GetRouterMap to GetRouterArray for ghttp.Server 2019-12-10 12:28:55 +08:00
add7dd5a45 merge develop 2019-12-09 23:22:49 +08:00
e40894ca45 add IsServiceHandler for ghttp.RouterItem 2019-12-09 23:19:39 +08:00
28825f5395 add gdebug.BuildInfo function; improving gproc 2019-12-09 21:53:44 +08:00
6ca5141020 some improving 2019-12-08 22:55:32 +08:00
fe4f8e1810 version updates 2019-12-05 19:46:50 +08:00
266 changed files with 8034 additions and 11075 deletions

View File

@ -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())

View File

@ -1,7 +1,7 @@
# MySQL数据库配置
[database]
debug = true
# debug = true
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test?parseTime=true&loc=Local"
#[database]

View File

@ -1,8 +1,6 @@
package main
import (
"fmt"
"github.com/gogf/gf/database/gdb"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/glog"
@ -23,7 +21,7 @@ func main() {
if err != nil {
panic(err)
}
db.SetDebug(true)
//db.SetDebug(false)
glog.SetPath("/tmp")
@ -36,7 +34,4 @@ func main() {
db.Table("user").Data(g.Map{"name": "smith"}).Where("uid=?", 1).Save()
db.PrintQueriedSqls()
fmt.Println(db.GetLastSql())
}

View File

@ -6,6 +6,7 @@ import (
func main() {
db := g.DB()
// 执行3条SQL查询
for i := 1; i <= 3; i++ {
db.Table("user").Where("id=?", i).One()

View File

@ -2,23 +2,16 @@ package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gtime"
)
func main() {
db := g.DB()
//db.SetDebug(true)
db.SetDebug(true)
type User struct {
Id int
Name *gtime.Time
}
user := new(User)
e := db.Table("test").Where("id", 10000).Struct(user)
one, e := db.Table("order.order o").LeftJoin("user.user u", "o.uid=u.id").Where("u.id", 1).One()
if e != nil {
panic(e)
}
g.Dump(user)
g.Dump(one)
}

View File

@ -0,0 +1,10 @@
package main
import (
"fmt"
"github.com/gogf/gf/debug/gdebug"
)
func main() {
fmt.Println(gdebug.BuildInfo())
}

View File

@ -1,60 +0,0 @@
// This is auto-generated by gf cli tool. You may not really want to edit it.
package defaults
import (
"database/sql"
"github.com/gogf/gf/database/gdb"
"github.com/gogf/gf/frame/g"
)
import (
"github.com/gogf/gf/os/gtime"
)
// User is the golang structure for table user.
type User struct {
Id int `orm:"id,primary" json:"id"`
Passport string `orm:"passport" json:"passport"`
Password string `orm:"password" json:"password"`
Nickname string `orm:"nickname,unique" json:"nickname"`
CreateTime *gtime.Time `orm:"create_time" json:"create_time"`
}
var (
// TableUser is the table name of user.
TableUser = "user"
// ModelUser is the model object of user.
ModelUser = g.DB("default").Table(TableUser).Safe()
)
// Inserts does "INSERT...INTO..." statement for inserting current object into table.
func (r *User) Insert() (result sql.Result, err error) {
return ModelUser.Data(r).Insert()
}
// Replace does "REPLACE...INTO..." statement for inserting current object into table.
// If there's already another same record in the table (it checks using primary key or unique index),
// it deletes it and insert this one.
func (r *User) Replace() (result sql.Result, err error) {
return ModelUser.Data(r).Replace()
}
// Save does "INSERT...INTO..." statement for inserting/updating current object into table.
// It updates the record if there's already another same record in the table
// (it checks using primary key or unique index).
func (r *User) Save() (result sql.Result, err error) {
return ModelUser.Data(r).Save()
}
// Update does "UPDATE...WHERE..." statement for updating current object from table.
// It updates the record if there's already another same record in the table
// (it checks using primary key or unique index).
func (r *User) Update() (result sql.Result, err error) {
return ModelUser.Data(r).Where(gdb.GetWhereConditionOfStruct(r)).Update()
}
// Delete does "DELETE FROM...WHERE..." statement for deleting current object from table.
func (r *User) Delete() (result sql.Result, err error) {
return ModelUser.Where(gdb.GetWhereConditionOfStruct(r)).Delete()
}

View File

@ -1,33 +0,0 @@
{
"viewpath" : "/home/www/templates/",
"database" : {
"default" : [
{
"host" : "127.0.0.1",
"port" : "3306",
"user" : "root",
"pass" : "123456",
"name" : "test",
"type" : "mysql",
"role" : "master",
"charset" : "utf8",
"priority" : "1"
},
{
"host" : "127.0.0.1",
"port" : "3306",
"user" : "root",
"pass" : "123456",
"name" : "test",
"type" : "mysql",
"role" : "master",
"charset" : "utf8",
"priority" : "1"
}
]
},
"redis" : {
"disk" : "127.0.0.1:6379,0",
"cache" : "127.0.0.1:6379,1"
}
}

View File

@ -1,11 +0,0 @@
viewpath = "/home/www/templates"
# MySQL数据库配置
[database]
debug = true
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
[redis]
disk = "127.0.0.1:6379,0"
cache = "127.0.0.1:6379,1"

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<config>
<!-- 模板引擎目录 -->
<viewpath>/home/www/templates/</viewpath>
<!-- MySQL数据库配置 -->
<database>
<default>
<host>127.0.0.1</host>
<port>3306</port>
<user>root</user>
<pass>123456</pass>
<name>test</name>
<role>master</role>
<type>mysql</type>
<charset>utf8</charset>
<priority>1</priority>
</default>
<default>
<host>127.0.0.1</host>
<port>3306</port>
<user>root</user>
<pass>123456</pass>
<name>test</name>
<role>master</role>
<type>mysql</type>
<charset>utf8</charset>
<priority>1</priority>
</default>
</database>
<!-- Redis数据库配置 -->
<redis>
<disk>127.0.0.1:6379,0</disk>
<cache>127.0.0.1:6379,1</cache>
</redis>
</config>

View File

@ -1,27 +0,0 @@
# 模板引擎目录
viewpath: /home/www/templates/
# MySQL数据库配置
database:
default:
- host: 127.0.0.1
port: 3306
user: root
pass: "8692651"
name: test
type: mysql
role: master
charset: utf8
priority: 1
- host: 127.0.0.1
port: 3306
user: root
pass: "8692651"
name: test
type: mysql
role: master
charset: utf8
priority: 1
# Redis数据库配置
redis:
default: 127.0.0.1:6379,0
cache : 127.0.0.1:6379,2

View File

@ -1,25 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func init() {
s := g.Server()
s.BindHandler("/apple", Apple)
s.BindHandler("/pen", Pen)
s.BindHandler("/apple-pen", ApplePen)
}
func Apple(r *ghttp.Request) {
r.Response.Write("Apple")
}
func Pen(r *ghttp.Request) {
r.Response.Write("Pen")
}
func ApplePen(r *ghttp.Request) {
r.Response.Write("Apple-Pen")
}

View File

@ -1,16 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type Order struct{}
func init() {
g.Server().BindObject("/{.struct}-{.method}", new(Order))
}
func (o *Order) List(r *ghttp.Request) {
r.Response.Write("List")
}

View File

@ -1,12 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/net/ghttp"
)
func init() {
ghttp.GetServer().BindHandler("/config", func(r *ghttp.Request) {
r.Response.Write(gins.Config().GetString("database.default.0.host"))
})
}

View File

@ -1,16 +0,0 @@
package demo
import (
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/gtime"
)
func init() {
ghttp.GetServer().BindHandler("/cookie", Cookie)
}
func Cookie(r *ghttp.Request) {
datetime := r.Cookie.Get("datetime")
r.Cookie.Set("datetime", gtime.Datetime())
r.Response.Write("datetime:" + datetime)
}

View File

@ -1,20 +0,0 @@
package demo
import (
"github.com/gogf/gf/net/ghttp"
)
type ControllerDomain struct{}
// 初始化控制器对象并绑定操作到Web Server
func init() {
// 只有localhost域名下才能访问该对象
// 对应URL为http://localhost:8199/test/show
// 通过该地址将无法访问到内容http://127.0.0.1:8199/test/show
ghttp.GetServer().Domain("localhost").BindObject("/domain", &ControllerDomain{})
}
// 用于对象映射
func (d *ControllerDomain) Show(r *ghttp.Request) {
r.Response.Write("It's show time bibi!")
}

View File

@ -1,24 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/gmvc"
"github.com/gogf/gf/net/ghttp"
)
type ControllerExit struct {
gmvc.Controller
}
func (c *ControllerExit) Init(r *ghttp.Request) {
c.Controller.Init(r)
c.Response.Write("exit, it will not print \"show\"")
c.Request.Exit()
}
func (c *ControllerExit) Show() {
c.Response.Write("show")
}
func init() {
ghttp.GetServer().BindController("/exit", &ControllerExit{})
}

View File

@ -1,36 +0,0 @@
package demo
import (
"fmt"
"github.com/gogf/gf/net/ghttp"
)
func Form(r *ghttp.Request) {
fmt.Println(r.GetPostMap())
fmt.Println(r.GetPostString("name"))
fmt.Println(r.GetPostString("age"))
}
func FormShow(r *ghttp.Request) {
r.Response.Write(`
<html>
<head>
<title>表单提交</title>
</head>
<body>
<form enctype="application/x-www-form-urlencoded" action="/form" method="post">
<input type="input" name="name" />
<input type="input" name="age" />
<input type="submit" value="submit" />
</form>
</body>
</html>
`)
}
func init() {
ghttp.GetServer().BindHandler("/form", Form)
ghttp.GetServer().BindHandler("/form/show", FormShow)
}

View File

@ -1,9 +0,0 @@
package demo
import "github.com/gogf/gf/net/ghttp"
func init() {
ghttp.GetServer().BindHandler("/", func(r *ghttp.Request) {
r.Response.Write("Hello World!")
})
}

View File

@ -1,30 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/frame/gmvc"
)
type Method struct {
gmvc.Controller
}
func init() {
// 第三个参数指定主要注册的方法,其他方法不注册,方法名称会自动追加到给定路由后面,构成新路由
// 以下注册会中注册两个新路由: /method/name, /method/age
g.Server().BindController("/method", new(Method), "Name, Age")
// 绑定路由到指定的方法执行,以下注册只会注册一个路由: /method-name
g.Server().BindControllerMethod("/method-name", new(Method), "Name")
}
func (c *Method) Name() {
c.Response.Write("John")
}
func (c *Method) Age() {
c.Response.Write("18")
}
func (c *Method) Info() {
c.Response.Write("Info")
}

View File

@ -1,20 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type Object struct{}
func init() {
g.Server().BindObject("/object", new(Object))
}
func (o *Object) Index(r *ghttp.Request) {
r.Response.Write("object index")
}
func (o *Object) Show(r *ghttp.Request) {
r.Response.Write("object show")
}

View File

@ -1,31 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type ObjectMethod struct{}
func init() {
obj := &ObjectMethod{}
g.Server().BindObject("/object-method", obj, "Show1, Show2, Show3")
g.Server().BindObjectMethod("/object-method-show1", obj, "Show1")
g.Server().Domain("localhost").BindObject("/object-method", obj, "Show4")
}
func (o *ObjectMethod) Show1(r *ghttp.Request) {
r.Response.Write("show 1")
}
func (o *ObjectMethod) Show2(r *ghttp.Request) {
r.Response.Write("show 2")
}
func (o *ObjectMethod) Show3(r *ghttp.Request) {
r.Response.Write("show 3")
}
func (o *ObjectMethod) Show4(r *ghttp.Request) {
r.Response.Write("show 4")
}

View File

@ -1,30 +0,0 @@
package demo
import "github.com/gogf/gf/net/ghttp"
// 测试绑定对象
type ObjectRest struct{}
func init() {
ghttp.GetServer().BindObjectRest("/object-rest", &ObjectRest{})
}
// RESTFul - GET
func (o *ObjectRest) Get(r *ghttp.Request) {
r.Response.Write("RESTFul HTTP Method GET")
}
// RESTFul - POST
func (c *ObjectRest) Post(r *ghttp.Request) {
r.Response.Write("RESTFul HTTP Method POST")
}
// RESTFul - DELETE
func (c *ObjectRest) Delete(r *ghttp.Request) {
r.Response.Write("RESTFul HTTP Method DELETE")
}
// 该方法无法映射,将会无法访问到
func (c *ObjectRest) Hello(r *ghttp.Request) {
r.Response.Write("Hello")
}

View File

@ -1,25 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type Product struct {
total int
}
func init() {
p := &Product{}
g.Server().BindHandler("/product/total", p.Total)
g.Server().BindHandler("/product/list/{page}.html", p.List)
}
func (p *Product) Total(r *ghttp.Request) {
p.total++
r.Response.Write("total: ", p.total)
}
func (p *Product) List(r *ghttp.Request) {
r.Response.Write("page: ", r.Get("page"))
}

View File

@ -1,34 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/frame/gmvc"
)
type Rest struct {
gmvc.Controller
}
func init() {
g.Server().BindControllerRest("/rest", &Rest{})
}
// RESTFul - GET
func (c *Rest) Get() {
c.Response.Write("RESTFul HTTP Method GET")
}
// RESTFul - POST
func (c *Rest) Post() {
c.Response.Write("RESTFul HTTP Method POST")
}
// RESTFul - DELETE
func (c *Rest) Delete() {
c.Response.Write("RESTFul HTTP Method DELETE")
}
// 该方法无法映射,将会无法访问到
func (c *Rest) Hello() {
c.Response.Write("Hello")
}

View File

@ -1,18 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/frame/gmvc"
)
type ControllerRule struct {
gmvc.Controller
}
func init() {
g.Server().BindController("/rule/{method}/:name", &ControllerRule{})
}
func (c *ControllerRule) Show() {
c.Response.Write(c.Request.Get("name"))
}

View File

@ -1,17 +0,0 @@
package demo
import (
"strconv"
"github.com/gogf/gf/net/ghttp"
)
func init() {
ghttp.GetServer().BindHandler("/session", Session)
}
func Session(r *ghttp.Request) {
id := r.Session.GetInt("id")
r.Session.Set("id", id+1)
r.Response.Write("id:" + strconv.Itoa(id))
}

View File

@ -1,23 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/gmvc"
"github.com/gogf/gf/net/ghttp"
)
type ControllerTemplate struct {
gmvc.Controller
}
func (c *ControllerTemplate) Info() {
c.View.Assign("name", "john")
c.View.Assigns(map[string]interface{}{
"age": 18,
"score": 100,
})
c.View.Display("view/user/index.tpl")
}
func init() {
ghttp.GetServer().BindController("/template", &ControllerTemplate{})
}

View File

@ -1,16 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func init() {
ghttp.GetServer().BindHandler("/template2", func(r *ghttp.Request) {
content, _ := g.View().Parse("index.tpl", map[string]interface{}{
"id": 123,
"name": "john",
})
r.Response.Write(content)
})
}

View File

@ -1,17 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/net/ghttp"
)
func init() {
gins.View().SetPath("/home/www/template/")
ghttp.GetServer().BindHandler("/template3", func(r *ghttp.Request) {
content, _ := gins.View().Parse("index.tpl", map[string]interface{}{
"id": 123,
"name": "john",
})
r.Response.Write(content)
})
}

View File

@ -1,40 +0,0 @@
package demo
import (
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/gfile"
)
func Upload(r *ghttp.Request) {
if f, h, e := r.FormFile("upload-file"); e == nil {
defer f.Close()
fname := gfile.Basename(h.Filename)
buffer := make([]byte, h.Size)
f.Read(buffer)
gfile.PutBytes("/tmp/"+fname, buffer)
r.Response.Write(fname + " uploaded successly")
} else {
r.Response.Write(e.Error())
}
}
func UploadShow(r *ghttp.Request) {
r.Response.Write(`
<html>
<head>
<title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" action="/upload" method="post">
<input type="file" name="upload-file" />
<input type="submit" value="upload" />
</form>
</body>
</html>
`)
}
func init() {
ghttp.GetServer().BindHandler("/upload", Upload)
ghttp.GetServer().BindHandler("/upload/show", UploadShow)
}

View File

@ -1,29 +0,0 @@
package demo
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/frame/gmvc"
)
type User struct {
gmvc.Controller
}
func init() {
s := g.Server()
s.BindController("/user", new(User))
s.BindController("/user/{.method}/{uid}", new(User), "Info")
s.BindController("/user/{.method}/{page}.html", new(User), "List")
}
func (u *User) Index() {
u.Response.Write("User")
}
func (u *User) Info() {
u.Response.Write("Info - Uid: ", u.Request.Get("uid"))
}
func (u *User) List() {
u.Response.Write("List - Page: ", u.Request.Get("page"))
}

View File

@ -1,19 +0,0 @@
package stats
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
var (
total int
)
func init() {
g.Server().BindHandler("/stats/total", showTotal)
}
func showTotal(r *ghttp.Request) {
total++
r.Response.Write("total:", total)
}

View File

@ -1,13 +0,0 @@
package main
import (
"fmt"
"github.com/gogf/gf/.example/frame/mvc/app/model/defaults"
"github.com/gogf/gf/database/gdb"
)
func main() {
u := defaults.User{Id: 1, Nickname: "test"}
fmt.Println(gdb.GetWhereConditionOfStruct(&u))
fmt.Println(u.Replace())
}

View File

@ -1,11 +0,0 @@
<html>
<head>
<title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" action="/upload" method="post">
<input type="file" name="upload-file" />
<input type="submit" value="upload" />
</form>
</body>
</html>

View File

@ -1,2 +0,0 @@
<h3>This is footer</h3>
<div style="color:red">tpl vals: {{.}}</div>

View File

@ -1,11 +0,0 @@
<html>
<head>
<title></title>
</head>
<body>
<h3>This is index</h3>
<p>tpl vals: {{.}}</p>
{{include "user/footer.tpl" }}
</body>
</html>

View File

@ -7,9 +7,7 @@ import (
func main() {
s := ghttp.GetServer()
s.BindHandler("/log/error", func(r *ghttp.Request) {
if j := r.GetJson(); j != nil {
r.Response.Write(j.Get("test"))
}
panic("OMG")
})
s.SetErrorLogEnabled(true)
s.SetPort(8199)

View File

@ -0,0 +1,17 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writeln(r.Get("amount"))
r.Response.Writeln(r.GetInt("amount"))
r.Response.Writeln(r.GetFloat32("amount"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,18 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
if r.GetInt("type") == 1 {
r.Response.Writeln("john")
}
r.Response.Writeln("smith")
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,15 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writef("name: %v, pass: %v", r.Get("name"), r.Get("pass"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,47 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/util/gvalid"
)
type RegisterReq struct {
Name string `p:"username" v:"required|length:6,30#请输入账号|账号长度为:min到:max位"`
Pass string `p:"password1" v:"required|length:6,30#请输入密码|密码长度不够"`
Pass2 string `p:"password2" v:"required|length:6,30|same:password1#请确认密码|两次密码不一致"`
}
type RegisterRes struct {
Code int `json:"code"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func main() {
s := g.Server()
s.BindHandler("/register", func(r *ghttp.Request) {
var req *RegisterReq
//fmt.Println(r.GetBody())
if err := r.Parse(&req); err != nil {
// Validation error.
if v, ok := err.(*gvalid.Error); ok {
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: v.FirstString(),
})
}
// Other error.
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: err.Error(),
})
}
// ...
r.Response.WriteJsonExit(RegisterRes{
Data: req,
})
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,15 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write(r.Get("array"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,15 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write(r.Get("map"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,15 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write(r.Get("name"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,18 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/input", func(r *ghttp.Request) {
r.Response.Writeln(r.Get("amount"))
})
s.BindHandler("/query", func(r *ghttp.Request) {
r.Response.Writeln(r.GetQuery("amount"))
})
s.SetPort(8199)
s.Run()
}

View File

@ -5,20 +5,20 @@ import (
"github.com/gogf/gf/net/ghttp"
)
type User struct {
Uid int `json:"uid"`
Name string `json:"name" params:"username"`
Pass1 string `json:"pass1" params:"password1,userpass1"`
Pass2 string `json:"pass2" params:"password3,userpass2"`
}
func main() {
type User struct {
Uid int `json:"uid"`
Name string `json:"name" p:"username"`
Pass1 string `json:"pass1" p:"password1"`
Pass2 string `json:"pass2" p:"password2"`
}
s := g.Server()
s.BindHandler("/user", func(r *ghttp.Request) {
user := new(User)
r.GetToStruct(user)
//r.GetPostToStruct(user)
//r.GetQueryToStruct(user)
var user *User
if err := r.Parse(&user); err != nil {
panic(err)
}
r.Response.WriteJson(user)
})
s.SetPort(8199)

View File

@ -0,0 +1,25 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
type User struct {
Id int `json:"id"`
Name string `json:"name"`
Pass1 string `json:"password1" p:"password1"`
Pass2 string `json:"password2" p:"password2"`
}
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
var user *User
if err := r.Parse(&user); err != nil {
r.Response.WriteExit(err)
}
r.Response.WriteExit(user)
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,37 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type RegisterReq struct {
Name string
Pass string `p:"password1"`
Pass2 string `p:"password2"`
}
type RegisterRes struct {
Code int `json:"code"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func main() {
s := g.Server()
s.BindHandler("/register", func(r *ghttp.Request) {
var req *RegisterReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: err.Error(),
})
}
// ...
r.Response.WriteJsonExit(RegisterRes{
Data: req,
})
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,37 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type RegisterReq struct {
Name string `p:"username" v:"required|length:6,30#请输入账号|账号长度为:min到:max位"`
Pass string `p:"password1" v:"required|length:6,30#请输入密码|密码长度不够"`
Pass2 string `p:"password2" v:"required|length:6,30|same:password1#请确认密码|两次密码不一致"`
}
type RegisterRes struct {
Code int `json:"code"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func main() {
s := g.Server()
s.BindHandler("/register", func(r *ghttp.Request) {
var req *RegisterReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: err.Error(),
})
}
// ...
r.Response.WriteJsonExit(RegisterRes{
Data: req,
})
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,46 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/util/gvalid"
)
type RegisterReq struct {
Name string `p:"username" v:"required|length:6,30#请输入账号|账号长度为:min到:max位"`
Pass string `p:"password1" v:"required|length:6,30#请输入密码|密码长度不够"`
Pass2 string `p:"password2" v:"required|length:6,30|same:password1#请确认密码|两次密码不一致"`
}
type RegisterRes struct {
Code int `json:"code"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func main() {
s := g.Server()
s.BindHandler("/register", func(r *ghttp.Request) {
var req *RegisterReq
if err := r.Parse(&req); err != nil {
// Validation error.
if v, ok := err.(*gvalid.Error); ok {
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: v.FirstString(),
})
}
// Other error.
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: err.Error(),
})
}
// ...
r.Response.WriteJsonExit(RegisterRes{
Data: req,
})
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,22 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
group := s.Group("/api")
group.ALL("/all", func(r *ghttp.Request) {
r.Response.Write("all")
})
group.GET("/get", func(r *ghttp.Request) {
r.Response.Write("get")
})
group.POST("/post", func(r *ghttp.Request) {
r.Response.Write("post")
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,38 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
type Object struct{}
func (o *Object) Show(r *ghttp.Request) {
r.Response.Writeln("Show")
}
func (o *Object) Delete(r *ghttp.Request) {
r.Response.Writeln("REST Delete")
}
func Handler(r *ghttp.Request) {
r.Response.Writeln("Handler")
}
func HookHandler(r *ghttp.Request) {
r.Response.Writeln("HOOK Handler")
}
func main() {
s := g.Server()
obj := new(Object)
s.Group("/api").Bind([]ghttp.GroupItem{
{"ALL", "*", HookHandler, ghttp.HOOK_BEFORE_SERVE},
{"ALL", "/handler", Handler},
{"ALL", "/obj", obj},
{"GET", "/obj/show", obj, "Show"},
{"REST", "/obj/rest", obj},
})
s.SetPort(8199)
s.Run()
}

View File

@ -5,7 +5,6 @@ import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/glog"
)
func MiddlewareAuth(r *ghttp.Request) {
@ -24,39 +23,37 @@ func MiddlewareCORS(r *ghttp.Request) {
func MiddlewareLog(r *ghttp.Request) {
r.Middleware.Next()
glog.Println(r.Response.Status, r.URL.Path)
g.Log().Println(r.Response.Status, r.URL.Path)
}
func main() {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(MiddlewareLog)
})
s.Use(MiddlewareLog)
s.Group("/api.v2", func(group *ghttp.RouterGroup) {
group.Middleware(MiddlewareAuth, MiddlewareCORS)
g.GET("/test", func(r *ghttp.Request) {
group.GET("/test", func(r *ghttp.Request) {
r.Response.Write("test")
})
g.Group("/order", func(group *ghttp.RouterGroup) {
g.GET("/list", func(r *ghttp.Request) {
group.Group("/order", func(group *ghttp.RouterGroup) {
group.GET("/list", func(r *ghttp.Request) {
r.Response.Write("list")
})
g.PUT("/update", func(r *ghttp.Request) {
group.PUT("/update", func(r *ghttp.Request) {
r.Response.Write("update")
})
})
g.Group("/user", func(group *ghttp.RouterGroup) {
g.GET("/info", func(r *ghttp.Request) {
group.Group("/user", func(group *ghttp.RouterGroup) {
group.GET("/info", func(r *ghttp.Request) {
r.Response.Write("info")
})
g.POST("/edit", func(r *ghttp.Request) {
group.POST("/edit", func(r *ghttp.Request) {
r.Response.Write("edit")
})
g.DELETE("/drop", func(r *ghttp.Request) {
group.DELETE("/drop", func(r *ghttp.Request) {
r.Response.Write("drop")
})
})
g.Group("/hook", func(group *ghttp.RouterGroup) {
group.Group("/hook", func(group *ghttp.RouterGroup) {
group.Hook("/*", ghttp.HOOK_BEFORE_SERVE, func(r *ghttp.Request) {
r.Response.Write("hook any")
})

View File

@ -1,9 +1,12 @@
package main
import "github.com/gogf/gf/net/ghttp"
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := ghttp.GetServer()
s := g.Server()
s.BindHandler("/user/:name", func(r *ghttp.Request) {
r.Response.Writeln(r.Router.Uri)
})

View File

@ -0,0 +1,16 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
// https://github.com/gogf/gf/issues/437
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.WriteTpl("client/layout.html")
})
s.SetPort(8199)
s.Run()
}

View File

@ -0,0 +1,9 @@
# custom gf build setting.
[compiler]
name = "app"
[compiler.varmap]
name = "GoFrame"
version = "1.10.1"
home-site = "https://goframe.org"

View File

@ -0,0 +1,11 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gbuild"
)
func main() {
g.Dump(gbuild.Info())
g.Dump(gbuild.Map())
}

View File

@ -1,6 +1,3 @@
// 多进程通信示例,
// 子进程每个1秒向父进程发送当前时间
// 父进程监听进程消息,收到后打印到终端。
package main
import (

View File

@ -2,16 +2,15 @@ package main
import (
"fmt"
"github.com/gogf/gf/os/gproc"
)
// 使用gproc kill指定其他进程(清确保运行该程序的用户有足够权限)
func main() {
pid := 28536
pid := 32556
m := gproc.NewManager()
m.AddProcess(pid)
m.KillAll()
err := m.KillAll()
fmt.Println(err)
m.WaitAll()
fmt.Printf("%d was killed\n", pid)
}

View File

@ -0,0 +1,12 @@
package main
import (
"fmt"
"github.com/gogf/gf/os/gproc"
)
func main() {
fmt.Println(gproc.Pid())
err := gproc.ShellRun("sleep 99999s")
fmt.Println(err)
}

View File

@ -12,16 +12,18 @@ func main() {
s.SetConfigWithMap(g.Map{
"SessionMaxAge": time.Minute,
})
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Second())
r.Response.Write("ok")
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
s.BindHandler("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Timestamp())
r.Response.Write("ok")
})
group.ALL("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
group.ALL("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
})
})
s.SetPort(8199)
s.Run()

View File

@ -14,16 +14,18 @@ func main() {
"SessionMaxAge": time.Minute,
"SessionStorage": gsession.NewStorageMemory(),
})
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Second())
r.Response.Write("ok")
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
s.BindHandler("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Timestamp())
r.Response.Write("ok")
})
group.ALL("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
group.ALL("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
})
})
s.SetPort(8199)
s.Run()

View File

@ -14,16 +14,18 @@ func main() {
"SessionMaxAge": time.Minute,
"SessionStorage": gsession.NewStorageRedisHashTable(g.Redis()),
})
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Second())
r.Response.Write("ok")
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
s.BindHandler("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Timestamp())
r.Response.Write("ok")
})
group.ALL("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
group.ALL("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
})
})
s.SetPort(8199)
s.Run()

View File

@ -14,16 +14,18 @@ func main() {
"SessionMaxAge": time.Minute,
"SessionStorage": gsession.NewStorageRedis(g.Redis()),
})
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Second())
r.Response.Write("ok")
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
s.BindHandler("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/set", func(r *ghttp.Request) {
r.Session.Set("time", gtime.Timestamp())
r.Response.Write("ok")
})
group.ALL("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Map())
})
group.ALL("/del", func(r *ghttp.Request) {
r.Session.Clear()
r.Response.Write("ok")
})
})
s.SetPort(8199)
s.Run()

View File

@ -1,3 +1,12 @@
[database]
debug = true
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test?parseTime=true&loc=Local"
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
[redis]
default = "127.0.0.1:6379,0"
cache = "127.0.0.1:6379,1"
[viewer]
delimiters = ["${", "}"]
autoencode = true

View File

@ -1,42 +0,0 @@
package main
import (
"fmt"
)
func main() {
fmt.Println("")
// 前景 背景 颜色
// ---------------------------------------
// 30 40 黑色
// 31 41 红色
// 32 42 绿色
// 33 43 黄色
// 34 44 蓝色
// 35 45 紫红色
// 36 46 青蓝色
// 37 47 白色
//
// 代码 意义
// -------------------------
// 0 终端默认设置
// 1 高亮显示
// 4 使用下划线
// 5 闪烁
// 7 反白显示
// 8 不可见
// 背景色彩 = 40-47
for b := 40; b <= 47; b++ {
// 前景色彩 = 30-37
for f := 30; f <= 37; f++ {
// 显示方式 = 0,1,4,5,7,8
for _, d := range []int{0, 1, 4, 5, 7, 8} {
fmt.Printf(" %c[%d;%d;%dm%s(f=%d,b=%d,d=%d)%c[0m ", 0x1B, d, b, f, "", f, b, d, 0x1B)
}
fmt.Println("")
}
fmt.Println("")
}
}

View File

@ -1,17 +1,11 @@
package main
import (
"fmt"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.Group("/api.v2", func(group *ghttp.RouterGroup) {
group.ALL("/test", func(r *ghttp.Request) {
r.Response.Write(r.GetRequest("nickname"))
})
})
s.SetPort(8199)
s.Run()
fmt.Println(g.Cfg().FilePath())
g.Cfg().Dump()
}

View File

@ -1,13 +1,11 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/text/gregex"
"fmt"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := `-abc`
m, err := gregex.MatchString(`^\-{1,2}a={0,1}(.*)`, s)
g.Dump(err)
g.Dump(m)
r := ghttp.PostContent("http://127.0.0.1:8199/test", `<doc><id>1</id><name>john</name><password1>123Abc!@#</password1><password2>123Abc!@#</password2></doc>`)
fmt.Println(r)
}

View File

@ -1,22 +0,0 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/glog"
)
func main() {
g.TryCatch(func() {
glog.Println("hello")
g.Throw("exception")
glog.Println("world")
})
g.TryCatch(func() {
glog.Println("hello")
g.Throw("exception")
glog.Println("world")
}, func(exception interface{}) {
glog.Error(exception)
})
}

View File

@ -7,18 +7,18 @@ import (
func main() {
type Ids struct {
Id int `json:"id"`
Uid int `json:"uid"`
Id int `c:"id"`
Uid int `c:"uid"`
}
type Base struct {
Ids
CreateTime string `json:"create_time"`
CreateTime string `c:"create_time"`
}
type User struct {
Base
Passport string `json:"passport"`
Password string `json:"password"`
Nickname string `json:"nickname"`
Passport string `c:"passport"`
Password string `c:"password"`
Nickname string `c:"nickname"`
}
user := new(User)
user.Id = 1
@ -27,5 +27,6 @@ func main() {
user.Passport = "johng"
user.Password = "123456"
user.CreateTime = "2019"
g.Dump(gconv.Map(user))
g.Dump(gconv.MapDeep(user))
}

View File

@ -1,35 +1,47 @@
# Donators
We currently accept donation by Alipay/WechatPay, please note your github/gitee account in your payment bill.
| Name | Channel | Amount
|---|---|---
|[hailaz](https://gitee.com/hailaz)|gitee|¥20.00
|[ireadx](https://github.com/ireadx)|alipay|¥301.00
|[mg91](https://gitee.com/mg91)|gitee|¥10.00
|[pibigstar](https://github.com/pibigstar)|alipay|¥10.00
|[tiangenglan](https://gitee.com/tiangenglan)|gitee|¥30.00
|[wxkj](https://gitee.com/wxkj)|wechat|¥10.00
|[zhuhuan12](https://gitee.com/zhuhuan12)|gitee|¥50.00
|[zfan_codes](https://gitee.com/zfan_codes)|gitee|¥10.00
|[arden](https://github.com/arden)|alipay|¥10.00
|[macnie](https://www.macnie.com)|wechat|¥100.00
|lah|wechat|¥100.00
|x*z|wechat|¥20.00
|潘兄|wechat|¥100.00
|Fly的狐狸|wechat|¥100.00
|全|alipay|¥100.00
|东东|wechat|¥100.00
|严宇轩|alipay|¥99.99
|土豆相公|alipay|¥66.60
|Hades|alipay|¥66.66
|蔡蔡|wechat|¥666.00
|上海金保证网络科技|bank|¥2000.00
|[foxhack](https://github.com/foxhack)|wechat|¥20.00
|*栈|wechat|¥5.00
|*络|wechat|¥10.00
|R*s|wechat|¥18.88
|粟*e|wechat|¥50.00
| Name | Channel | Amount | Comment
|---|---|--- | ---
|[hailaz](https://gitee.com/hailaz)|gitee|¥20.00 |
|[ireadx](https://github.com/ireadx)|alipay|¥301.00 |
|[mg91](https://gitee.com/mg91)|gitee|¥10.00 |
|[pibigstar](https://github.com/pibigstar)|alipay|¥10.00 |
|[tiangenglan](https://gitee.com/tiangenglan)|gitee|¥30.00 |
|[wxkj](https://gitee.com/wxkj)|wechat|¥10.00 |
|[zhuhuan12](https://gitee.com/zhuhuan12)|gitee|¥50.00 |
|[zfan_codes](https://gitee.com/zfan_codes)|gitee|¥10.00 |
|[arden](https://github.com/arden)|alipay|¥10.00 |
|[macnie](https://www.macnie.com)|wechat|¥100.00 |
|lah|wechat|¥100.00 |
|x*z|wechat|¥20.00 |
|潘兄|wechat|¥100.00 |
|Fly的狐狸|wechat|¥100.00 |
|全|alipay|¥100.00 |
|东东|wechat|¥100.00 |
|严宇轩|alipay|¥99.99 |
|土豆相公|alipay|¥66.60 |
|Hades|alipay|¥66.66 |
|蔡蔡|wechat|¥666.00 | gf越来越强
|上海金保证网络科技|bank|¥2000.00 |
|[foxhack](https://github.com/foxhack)|wechat|¥20.00 |
|*栈|wechat|¥5.00 |
|*络|wechat|¥10.00|
|M*e|wechat|¥20.00|
|*G|wechat|¥10.00|
|E*_|wechat|¥10.00|
|A*y|wechat|¥1.00| 感谢大佬goframe
|K*e|wechat|¥168.00| 感谢老大
|*雨|wechat|¥100.00|
|*洁|wechat|¥10.00|赞助你肥宅快乐水
|R*s|wechat|¥18.88| 谢谢GF辛苦了
|粟*e|wechat|¥50.00|
|[李超](https://github.com/effortlee)|wechat|¥124.00|
|张炳贤|wechat+qq|¥600.00|
|[王哈哈](https://gitee.com/develop1024)|wechat|¥6.66| 希望gf越来越好
|夕景|alipay+qq|¥9.96+3.57|
<img src="https://goframe.org/images/donate.png"/>

View File

@ -9,7 +9,12 @@
English | [简体中文](README_ZH.MD)
`GF(GoFrame)` is a modular, full-featured and production-ready application development framework of golang. Providing a series of core components and dozens of practical modules, such as: memcache, configure, validator, logging, array/queue/set/map containers, timer/timing tasks, file/memory lock, object pool, database ORM, etc. Supporting web server integrated with router, cookie, session, middleware, logger, template, https, hooks, rewrites and many more features.
`GF(GoFrame)` is a modular, full-featured and production-ready application development framework of golang.
Providing a series of core components and dozens of practical modules,
such as: memcache, configure, validator, logging, array/queue/set/map containers,
timer/timing tasks, file/memory lock, object pool, database ORM, etc.
Supporting web server integrated with router, cookie, session, middleware, logger,
template, https, hooks, rewrites and many more features.
# Installation
@ -23,7 +28,7 @@ require github.com/gogf/gf latest
# Limitation
```
golang version >= 1.11
golang version >= 1.10
```
# Documentation
@ -36,27 +41,6 @@ golang version >= 1.11
<img src="https://goframe.org/images/arch.png?v=10"/>
</div>
# Quick Start
```go
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write("Hello World")
})
s.Run()
}
```
[More Features...](https://goframe.org/start/index)
# License

View File

@ -8,8 +8,11 @@
[English](README.MD) | 简体中文
`GF(Go Frame)`是一款模块化、高性能、生产级Go应用开发框架。提供了常用的核心开发组件缓存、日志、文件、时间、队列、数组、集合、字符串、定时器、命令行、文件锁、内存锁、对象池、连接池、资源管理、数据校验、数据编码、文件监控、定时任务、数据库ORM、TCP/UDP组件、进程管理/通信、
并发安全容器等等。并提供了Web服务开发的系列核心组件Router、Cookie、Session、Middleware、服务注册、配置管理、模板引擎等等支持热重启、热更新、多域名、多端口、多服务、HTTPS、Rewrite等特性。
`GF(Go Frame)`是一款模块化、高性能、生产级Go基础开发框架。实现了比较完善的基础设施建设,包括常用的核心开发组件,
如:缓存、日志、文件、时间、队列、数组、集合、字符串、定时器、命令行、文件锁、内存锁、对象池、连接池、资源管理、数据校验、数据编码、文件监控、
定时任务、数据库ORM、TCP/UDP组件、进程管理/通信、并发安全容器等等。
并提供了Web服务开发的系列核心组件Router、Cookie、Session、Middleware、服务注册、配置管理、模板引擎等等
支持热重启、热更新、多域名、多端口、多服务、HTTPS、Rewrite等特性。
# 特点
@ -18,7 +21,6 @@
* 简便及可维护性为宗旨;
* 详尽的开发文档及示例;
* 完善的本地中文化支持;
* 致力于项目的通用方案;
* 更适合企业及团队使用;
* 更多请查阅文档及源码;
@ -49,27 +51,6 @@ golang版本 >= 1.11
接口文档:[https://godoc.org/github.com/gogf/gf](https://godoc.org/github.com/gogf/gf)
# 使用
```go
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write("Hello World")
})
s.Run()
}
```
[更多..](https://goframe.org/start/index)
# 协议
`GF` 使用非常友好的 [MIT](LICENSE) 开源协议进行发布,永久`100%`开源免费。

View File

@ -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...)
@ -609,6 +625,35 @@ func (a *Array) CountValues() map[interface{}]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *Array) Iterator(f func(k int, v interface{}) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *Array) IteratorAsc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *Array) IteratorDesc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *Array) String() string {
a.mu.RLock()

View File

@ -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.
@ -621,6 +637,35 @@ func (a *IntArray) CountValues() map[int]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *IntArray) Iterator(f func(k int, v int) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *IntArray) IteratorAsc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *IntArray) IteratorDesc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *IntArray) String() string {
return "[" + a.Join(",") + "]"

View File

@ -622,6 +622,35 @@ func (a *StrArray) CountValues() map[string]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *StrArray) Iterator(f func(k int, v string) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *StrArray) IteratorAsc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *StrArray) IteratorDesc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *StrArray) String() string {
a.mu.RLock()

View File

@ -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.
@ -554,6 +570,35 @@ func (a *SortedArray) CountValues() map[interface{}]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *SortedArray) Iterator(f func(k int, v interface{}) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedArray) IteratorAsc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedArray) IteratorDesc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *SortedArray) String() string {
a.mu.RLock()

View File

@ -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.
@ -546,6 +562,35 @@ func (a *SortedIntArray) CountValues() map[int]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *SortedIntArray) Iterator(f func(k int, v int) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedIntArray) IteratorAsc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedIntArray) IteratorDesc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *SortedIntArray) String() string {
return "[" + a.Join(",") + "]"

View File

@ -547,6 +547,35 @@ func (a *SortedStrArray) CountValues() map[string]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *SortedStrArray) Iterator(f func(k int, v string) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedStrArray) IteratorAsc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedStrArray) IteratorDesc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *SortedStrArray) String() string {
a.mu.RLock()

View File

@ -450,3 +450,50 @@ func TestArray_Json(t *testing.T) {
gtest.Assert(user.Scores, data["Scores"])
})
}
func TestArray_Iterator(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -484,3 +484,50 @@ func TestIntArray_Json(t *testing.T) {
gtest.Assert(user.Scores, data["Scores"])
})
}
func TestIntArray_Iterator(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewIntArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -488,3 +488,50 @@ func TestStrArray_Json(t *testing.T) {
gtest.Assert(user.Scores, data["Scores"])
})
}
func TestStrArray_Iterator(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewStrArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -587,3 +587,50 @@ func TestSortedArray_Json(t *testing.T) {
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
})
}
func TestSortedArray_Iterator(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewSortedArrayFrom(slice, gutil.ComparatorString)
gtest.Case(t, func() {
array.Iterator(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -466,3 +466,50 @@ func TestSortedIntArray_Json(t *testing.T) {
gtest.Assert(user.Scores, []int{98, 99, 100})
})
}
func TestSortedIntArray_Iterator(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewSortedIntArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -476,3 +476,50 @@ func TestSortedStrArray_Json(t *testing.T) {
gtest.Assert(user.Scores, []string{"A", "A", "A+"})
})
}
func TestSortedStrArray_Iterator(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewSortedStrArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -364,6 +364,7 @@ func (l *List) Iterator(f func(e *Element) bool) {
// If <f> returns true, then it continues iterating; or false to stop.
func (l *List) IteratorAsc(f func(e *Element) bool) {
l.mu.RLock()
defer l.mu.RUnlock()
length := l.list.Len()
if length > 0 {
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
@ -372,13 +373,13 @@ func (l *List) IteratorAsc(f func(e *Element) bool) {
}
}
}
l.mu.RUnlock()
}
// IteratorDesc iterates the list in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (l *List) IteratorDesc(f func(e *Element) bool) {
l.mu.RLock()
defer l.mu.RUnlock()
length := l.list.Len()
if length > 0 {
for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
@ -387,7 +388,6 @@ func (l *List) IteratorDesc(f func(e *Element) bool) {
}
}
}
l.mu.RUnlock()
}
// Join joins list elements with a string <glue>.

View File

@ -7,7 +7,9 @@
package glist_test
import (
"container/list"
"fmt"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/container/glist"
)
@ -35,3 +37,64 @@ 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 reading from head using IteratorAsc.
l.IteratorAsc(func(e *glist.Element) bool {
fmt.Print(e.Value)
return true
})
fmt.Println()
// iterate reading from tail using IteratorDesc.
l.IteratorDesc(func(e *glist.Element) bool {
fmt.Print(e.Value)
return true
})
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
//12345678910
//10987654321
//[1,2,3,4,5,"M",7,8,9,10]
}

View File

@ -12,6 +12,7 @@ import (
"sync/atomic"
)
// Bool is a struct for concurrent-safe operation for type bool.
type Bool struct {
value int32
}
@ -21,7 +22,7 @@ var (
bytesFalse = []byte("false")
)
// NewBool returns a concurrent-safe object for bool type,
// NewBool creates and returns a concurrent-safe object for bool type,
// with given initial value <value>.
func NewBool(value ...bool) *Bool {
t := &Bool{}
@ -50,13 +51,13 @@ func (v *Bool) Set(value bool) (old bool) {
return
}
// Val atomically loads t.valueue.
// Val atomically loads and returns t.valueue.
func (v *Bool) Val() bool {
return atomic.LoadInt32(&v.value) > 0
}
// Cas executes the compare-and-swap operation for value.
func (v *Bool) Cas(old, new bool) bool {
func (v *Bool) Cas(old, new bool) (swapped bool) {
var oldInt32, newInt32 int32
if old {
oldInt32 = 1

View File

@ -12,11 +12,12 @@ import (
"sync/atomic"
)
// Byte is a struct for concurrent-safe operation for type byte.
type Byte struct {
value int32
}
// NewByte returns a concurrent-safe object for byte type,
// NewByte creates and returns a concurrent-safe object for byte type,
// with given initial value <value>.
func NewByte(value ...byte) *Byte {
if len(value) > 0 {
@ -37,7 +38,7 @@ func (v *Byte) Set(value byte) (old byte) {
return byte(atomic.SwapInt32(&v.value, int32(value)))
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Byte) Val() byte {
return byte(atomic.LoadInt32(&v.value))
}
@ -48,7 +49,7 @@ func (v *Byte) Add(delta byte) (new byte) {
}
// Cas executes the compare-and-swap operation for value.
func (v *Byte) Cas(old, new byte) bool {
func (v *Byte) Cas(old, new byte) (swapped bool) {
return atomic.CompareAndSwapInt32(&v.value, int32(old), int32(new))
}

View File

@ -13,11 +13,12 @@ import (
"sync/atomic"
)
// Bytes is a struct for concurrent-safe operation for type []byte.
type Bytes struct {
value atomic.Value
}
// NewBytes returns a concurrent-safe object for []byte type,
// NewBytes creates and returns a concurrent-safe object for []byte type,
// with given initial value <value>.
func NewBytes(value ...[]byte) *Bytes {
t := &Bytes{}
@ -40,7 +41,7 @@ func (v *Bytes) Set(value []byte) (old []byte) {
return
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Bytes) Val() []byte {
if s := v.value.Load(); s != nil {
return s.([]byte)

View File

@ -14,11 +14,12 @@ import (
"unsafe"
)
// Float32 is a struct for concurrent-safe operation for type float32.
type Float32 struct {
value uint32
}
// NewFloat32 returns a concurrent-safe object for float32 type,
// NewFloat32 creates and returns a concurrent-safe object for float32 type,
// with given initial value <value>.
func NewFloat32(value ...float32) *Float32 {
if len(value) > 0 {
@ -39,7 +40,7 @@ func (v *Float32) Set(value float32) (old float32) {
return math.Float32frombits(atomic.SwapUint32(&v.value, math.Float32bits(value)))
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Float32) Val() float32 {
return math.Float32frombits(atomic.LoadUint32(&v.value))
}
@ -61,7 +62,7 @@ func (v *Float32) Add(delta float32) (new float32) {
}
// Cas executes the compare-and-swap operation for value.
func (v *Float32) Cas(old, new float32) bool {
func (v *Float32) Cas(old, new float32) (swapped bool) {
return atomic.CompareAndSwapUint32(&v.value, math.Float32bits(old), math.Float32bits(new))
}

View File

@ -14,11 +14,12 @@ import (
"unsafe"
)
// Float64 is a struct for concurrent-safe operation for type float64.
type Float64 struct {
value uint64
}
// NewFloat64 returns a concurrent-safe object for float64 type,
// NewFloat64 creates and returns a concurrent-safe object for float64 type,
// with given initial value <value>.
func NewFloat64(value ...float64) *Float64 {
if len(value) > 0 {
@ -39,7 +40,7 @@ func (v *Float64) Set(value float64) (old float64) {
return math.Float64frombits(atomic.SwapUint64(&v.value, math.Float64bits(value)))
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Float64) Val() float64 {
return math.Float64frombits(atomic.LoadUint64(&v.value))
}
@ -61,7 +62,7 @@ func (v *Float64) Add(delta float64) (new float64) {
}
// Cas executes the compare-and-swap operation for value.
func (v *Float64) Cas(old, new float64) bool {
func (v *Float64) Cas(old, new float64) (swapped bool) {
return atomic.CompareAndSwapUint64(&v.value, math.Float64bits(old), math.Float64bits(new))
}

View File

@ -12,11 +12,12 @@ import (
"sync/atomic"
)
// Int is a struct for concurrent-safe operation for type int.
type Int struct {
value int64
}
// NewInt returns a concurrent-safe object for int type,
// NewInt creates and returns a concurrent-safe object for int type,
// with given initial value <value>.
func NewInt(value ...int) *Int {
if len(value) > 0 {
@ -37,7 +38,7 @@ func (v *Int) Set(value int) (old int) {
return int(atomic.SwapInt64(&v.value, int64(value)))
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Int) Val() int {
return int(atomic.LoadInt64(&v.value))
}
@ -48,7 +49,7 @@ func (v *Int) Add(delta int) (new int) {
}
// Cas executes the compare-and-swap operation for value.
func (v *Int) Cas(old, new int) bool {
func (v *Int) Cas(old, new int) (swapped bool) {
return atomic.CompareAndSwapInt64(&v.value, int64(old), int64(new))
}

View File

@ -12,11 +12,12 @@ import (
"sync/atomic"
)
// Int32 is a struct for concurrent-safe operation for type int32.
type Int32 struct {
value int32
}
// NewInt32 returns a concurrent-safe object for int32 type,
// NewInt32 creates and returns a concurrent-safe object for int32 type,
// with given initial value <value>.
func NewInt32(value ...int32) *Int32 {
if len(value) > 0 {
@ -37,7 +38,7 @@ func (v *Int32) Set(value int32) (old int32) {
return atomic.SwapInt32(&v.value, value)
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Int32) Val() int32 {
return atomic.LoadInt32(&v.value)
}
@ -48,7 +49,7 @@ func (v *Int32) Add(delta int32) (new int32) {
}
// Cas executes the compare-and-swap operation for value.
func (v *Int32) Cas(old, new int32) bool {
func (v *Int32) Cas(old, new int32) (swapped bool) {
return atomic.CompareAndSwapInt32(&v.value, old, new)
}

View File

@ -12,11 +12,12 @@ import (
"sync/atomic"
)
// Int64 is a struct for concurrent-safe operation for type int64.
type Int64 struct {
value int64
}
// NewInt64 returns a concurrent-safe object for int64 type,
// NewInt64 creates and returns a concurrent-safe object for int64 type,
// with given initial value <value>.
func NewInt64(value ...int64) *Int64 {
if len(value) > 0 {
@ -37,7 +38,7 @@ func (v *Int64) Set(value int64) (old int64) {
return atomic.SwapInt64(&v.value, value)
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Int64) Val() int64 {
return atomic.LoadInt64(&v.value)
}
@ -48,7 +49,7 @@ func (v *Int64) Add(delta int64) (new int64) {
}
// Cas executes the compare-and-swap operation for value.
func (v *Int64) Cas(old, new int64) bool {
func (v *Int64) Cas(old, new int64) (swapped bool) {
return atomic.CompareAndSwapInt64(&v.value, old, new)
}

View File

@ -12,11 +12,12 @@ import (
"sync/atomic"
)
// Interface is a struct for concurrent-safe operation for type interface{}.
type Interface struct {
value atomic.Value
}
// NewInterface returns a concurrent-safe object for interface{} type,
// NewInterface creates and returns a concurrent-safe object for interface{} type,
// with given initial value <value>.
func NewInterface(value ...interface{}) *Interface {
t := &Interface{}
@ -39,7 +40,7 @@ func (v *Interface) Set(value interface{}) (old interface{}) {
return
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *Interface) Val() interface{} {
return v.value.Load()
}

View File

@ -12,11 +12,12 @@ import (
"sync/atomic"
)
// String is a struct for concurrent-safe operation for type string.
type String struct {
value atomic.Value
}
// NewString returns a concurrent-safe object for string type,
// NewString creates and returns a concurrent-safe object for string type,
// with given initial value <value>.
func NewString(value ...string) *String {
t := &String{}
@ -38,7 +39,7 @@ func (v *String) Set(value string) (old string) {
return
}
// Val atomically loads t.value.
// Val atomically loads and returns t.value.
func (v *String) Val() string {
s := v.value.Load()
if s != nil {

Some files were not shown because too many files have changed in this diff Show More