Skip to content

Commit 5f75b21

Browse files
committed
新增测试示例
1 parent 8c4f144 commit 5f75b21

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2165
-23
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,39 @@ gitbook serve
2626
```
2727

2828
[http://localhost:4000/](http://localhost:4000/)
29+
30+
31+
## 语言哲学
32+
33+
换一种语言,意味着换一种信仰
34+
35+
语言不同,哲学不同,思维不同,最佳实践自然不同
36+
37+
[我为什么放弃Go语言](https://www.cnblogs.com/findumars/p/4097888.html)
38+
39+
[驳狗屎文 "我为什么放弃Go语言"](https://blog.csdn.net/cxlzxi/article/details/50284975)
40+
41+
42+
## 常用语法特性
43+
44+
map 通过双赋值检测某个键存在
45+
```
46+
elem, ok = m[key]
47+
```
48+
49+
指针操作符
50+
```
51+
& 变量取地址
52+
* 指针取值
53+
```
54+
55+
struct 定义json时,omitempty忽略零值和空值
56+
```
57+
Field int `json:"myName"` // 以原始"myName"作为键名
58+
Field int `json:"myName,omitempty"` // 以原始"myName"作为键名,如果为空则忽略字段序列化
59+
Field int `json:",omitempty"` // 以原始"Field"作为键名,
60+
Field int `json:"-"` // 忽略字段序列化
61+
Field int `json:"-,"` // 以"-"作为键名
62+
```
63+
64+
只有发送者才能关闭 channel,而不是接收者。向一个已经关闭的 channel 发送数据会引起 panic

apis/daily_sentence.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,31 @@
11
package apis
2+
3+
import (
4+
"fmt"
5+
"github.com/zhanghe06/gin_project/dbs"
6+
"github.com/zhanghe06/gin_project/models"
7+
)
8+
9+
func UpdateDailySentenceTransaction(condition map[string]interface{}, updateData map[string]interface{}) (rows int64, err error) {
10+
tx := dbs.DbClient.Begin()
11+
defer func() {
12+
if rec := recover(); rec != nil {
13+
err = fmt.Errorf("%v", rec)
14+
fmt.Println(err.Error())
15+
tx.Rollback()
16+
}
17+
}()
18+
var dailySentences []*models.DailySentence
19+
20+
resultFind := tx.Set("gorm:query_option", "FOR UPDATE").Where(condition).Find(&dailySentences)
21+
if resultFind.Error != nil {
22+
panic(resultFind.Error)
23+
}
24+
25+
resultUpdate := tx.Model(&dailySentences).Updates(updateData)
26+
if resultUpdate.Error != nil {
27+
panic(resultUpdate.Error)
28+
}
29+
tx.Commit()
30+
return resultUpdate.RowsAffected, nil
31+
}

controllers/daily_sentence.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ package controllers
22

33
import (
44
"fmt"
5+
"net/http"
6+
"time"
7+
58
"github.com/gin-gonic/gin"
69
"github.com/go-sql-driver/mysql"
710
"github.com/jinzhu/gorm"
11+
12+
"github.com/zhanghe06/gin_project/apis"
813
"github.com/zhanghe06/gin_project/dbs"
914
"github.com/zhanghe06/gin_project/models"
1015
"github.com/zhanghe06/gin_project/requests"
1116
"github.com/zhanghe06/gin_project/utils"
12-
"net/http"
13-
"time"
1417
)
1518

1619
// 获取列表
@@ -313,3 +316,44 @@ func ScoreDailySentenceHandler(c *gin.Context) {
313316
// 注意: 这里的res.Value和dailySentence一样, 更新的字段仅为updates传入的参数, 其余数据库自动修改的字段不会更新到这里
314317
c.JSON(http.StatusOK, dailySentence)
315318
}
319+
320+
321+
322+
// 更新记录
323+
//curl -X POST \
324+
// http://0.0.0.0:8080/v1/daily_sentence/transaction \
325+
// -H 'Content-Type: application/json' \
326+
// -d '{
327+
// "id": "1",
328+
// "Title": "this is a test",
329+
// "Classification": "news"
330+
//}'
331+
func UpdateDailySentenceTransactionHandler(c *gin.Context) {
332+
// 意外异常
333+
defer func(c *gin.Context) {
334+
if rec := recover(); rec != nil {
335+
err := fmt.Errorf("%v", rec)
336+
c.AbortWithError(http.StatusInternalServerError, err)
337+
}
338+
}(c)
339+
340+
var dailySentenceRequest requests.UpdateDailySentenceTransactionRequests
341+
342+
// 参数校验
343+
if err := c.ShouldBindJSON(&dailySentenceRequest); err != nil {
344+
c.AbortWithError(http.StatusBadRequest, err)
345+
return
346+
}
347+
348+
condition := map[string]interface{}{"id": dailySentenceRequest.ID}
349+
updateData := map[string]interface{}{}
350+
if dailySentenceRequest.Title != "" {
351+
updateData["title"] = dailySentenceRequest.Title
352+
}
353+
rows, err := apis.UpdateDailySentenceTransaction(condition, updateData)
354+
if err != nil {
355+
c.AbortWithError(http.StatusBadRequest, err)
356+
return
357+
}
358+
c.JSON(http.StatusOK, gin.H{"rows": rows})
359+
}

controllers/stream.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package controllers
2+
3+
import (
4+
"fmt"
5+
"github.com/gin-gonic/gin"
6+
"io"
7+
"net/http"
8+
"time"
9+
)
10+
11+
// 流式请求(利用 H5 的新特性 SSE)
12+
// curl -i -X GET http://0.0.0.0:8080/v1/stream/sse
13+
func StreamSSEHandler(c *gin.Context) {
14+
chanStream := make(chan int, 10)
15+
go func() {
16+
defer close(chanStream)
17+
for i := 0; i < 5; i++ {
18+
chanStream <- i
19+
time.Sleep(time.Second * 1)
20+
}
21+
}()
22+
c.Stream(func(w io.Writer) bool {
23+
if msg, ok := <-chanStream; ok {
24+
c.SSEvent("message", msg)
25+
return true
26+
}
27+
return false
28+
})
29+
}
30+
31+
// 流式请求
32+
// curl -i -X GET http://0.0.0.0:8080/v1/stream/crd
33+
func StreamCRDHandler(c *gin.Context) {
34+
chanStream := make(chan int, 10)
35+
go func() {
36+
defer close(chanStream)
37+
for i := 0; i < 5; i++ {
38+
chanStream <- i
39+
time.Sleep(time.Second * 1)
40+
}
41+
}()
42+
c.Stream(func(w io.Writer) bool {
43+
if msg, ok := <-chanStream; ok {
44+
data := fmt.Sprintf("%d\n", msg)
45+
c.Data(http.StatusOK, "text/event-stream", []byte(data))
46+
return true
47+
}
48+
return false
49+
})
50+
}

docs/deploy/govendor.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ govendor sync
2929
govendor add +e
3030
```
3131

32-
更新项目依赖
32+
更新项目依赖(新增依赖 + 更新已有依赖)
3333
```
34-
govendor update github.com/gin-gonic/gin
34+
govendor add +e
35+
govendor update +v
3536
```
3637

3738
中国特色依赖

docs/framework/gin.md

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Gin
22

3-
https://github.com/gin-gonic/gin
3+
[https://github.com/gin-gonic/gin](https://github.com/gin-gonic/gin)
44

55
```
66
go get -u github.com/gin-gonic/gin
@@ -35,21 +35,86 @@ go test tests/*
3535

3636
## 中间件
3737

38-
在 Middleware02 中Abort, 执行结果
38+
测试示例
39+
```go
40+
package middlewares
41+
42+
import (
43+
"fmt"
44+
"github.com/gin-gonic/gin"
45+
)
46+
47+
func Middleware01() gin.HandlerFunc {
48+
return func(c *gin.Context) {
49+
defer func() {
50+
fmt.Println("Middleware01 Defer")
51+
}()
52+
fmt.Println("Middleware01 Before")
53+
c.Next()
54+
fmt.Println("Middleware01 After")
55+
}
56+
}
57+
```
58+
59+
执行结果
3960
```
4061
Middleware01 Before
4162
Middleware02 Before
4263
Middleware03 Before
4364
65+
...
66+
67+
Middleware03 After
68+
Middleware03 Defer
69+
Middleware02 After
70+
Middleware02 Defer
71+
Middleware01 After
72+
Middleware01 Defer
73+
```
74+
75+
### Abort without return
76+
77+
1、在 Middleware02 中 c.Next() 前 Abort, 执行结果
78+
```
79+
Middleware01 Before
80+
Middleware02 Before
81+
Middleware02 After
82+
Middleware02 Defer
83+
Middleware01 After
84+
Middleware01 Defer
85+
```
86+
87+
2、在 Middleware02 中 c.Next() 后 Abort, 不会产生影响,正常执行
88+
89+
3、在 Middleware02 中 defer 里 Abort, 不会产生影响,正常执行
90+
91+
92+
### Abort with return
93+
94+
1、在 Middleware02 中 c.Next() 前 Abort, 执行结果
95+
```
96+
Middleware01 Before
97+
Middleware02 Before
98+
Middleware02 Defer
4499
Middleware01 After
100+
Middleware01 Defer
45101
```
46102

103+
2、在 Middleware02 中 c.Next() 后 Abort, 不会产生影响,正常执行
104+
105+
3、在 Middleware02 中 defer 里 Abort, 不会产生影响,正常执行
106+
107+
47108
中间件使用`goroutines`注意:
48109

49110
https://github.com/gin-gonic/gin#goroutines-inside-a-middleware
50111

51112

52-
## binding
113+
## struct binding tag for Bind/ShouldBind
114+
115+
[go-playground/validator.v8](https://github.com/go-playground/validator)
116+
[hdr-Baked_In_Validators_and_Tags](http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags)
117+
[gin_validator_v8_to_v9](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
53118

54119
- required
55120
- omitempty

docs/framework/gorm.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,24 @@ http://gorm.io/docs/update.html
100100
## autocommit
101101

102102
设置`&autocommit=false`貌似没有影响,源码没有查到此参数设置,待查
103+
104+
105+
## Sql 注入
106+
107+
错误方式
108+
```
109+
db = db.Where("name LIKE '%"+args.Name+"%'")
110+
```
111+
112+
正确方式
113+
```
114+
name := fmt.Sprintf("%%%s%%", args.Name)
115+
db = db.Where("name LIKE ?", name)
116+
```
117+
118+
拼接sql,应该使用占位符`?`,避免直接解析
119+
120+
POC
121+
```
122+
%') and sleep(1);-- -
123+
```

docs/framework/gotpl.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# gotpl
2+
3+
https://github.com/tsg/gotpl

docs/framework/grequests.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# GRequests
2+
3+
```
4+
go get -u github.com/levigross/grequests
5+
```

0 commit comments

Comments
 (0)