Skip to content

Commit ecb0597

Browse files
committed
两张表在数组内 一对一 关联查询实现 50%
1 parent 7392001 commit ecb0597

File tree

5 files changed

+84
-45
lines changed

5 files changed

+84
-45
lines changed

README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,4 @@
1919
- [ ] 5.实现两张表在数组内 一对一 关联查询
2020
- [ ] 6.实现两张表在数组内 一对多 关联查询
2121
- [ ] 7.实现SQL的 column, order by, group by等功能。
22-
- [ ] 8.实现增、删、改
23-
24-
22+
- [ ] 8.实现增、删、改

db/db.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
var db *sqlx.DB
1313

14-
const dataSourceName = "root:123456@tcp(localhost:3306)/apijson"
14+
const dataSourceName = "root:123456@tcp(localhost:3306)/sys"
1515

1616
type TableMeta struct {
1717
Name string

db/sqlparser.go

+43-19
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import (
88
"strings"
99
)
1010

11-
type SQLParseObject struct {
11+
type SQLParser struct {
12+
Key string
1213
LoadFunc func(s string) interface{}
13-
QueryFirst bool
14+
RequestMap map[string]interface{}
1415
Values []interface{}
1516

1617
table string
@@ -20,20 +21,43 @@ type SQLParseObject struct {
2021
limit int
2122
page int
2223
withPage bool
24+
25+
children []SQLParser
2326
}
2427

25-
func (o *SQLParseObject) From(key string, fieldMap map[string]interface{}) error {
26-
if strings.HasSuffix(key, "[]") {
27-
o.QueryFirst = false
28-
return o.parseListQuery(fieldMap)
28+
func (o *SQLParser) GetData() (interface{}, error) {
29+
if strings.HasSuffix(o.Key, "[]") {
30+
if err := o.parseListQuery(); err != nil {
31+
return nil, err
32+
}
33+
values, err := QueryAll(o.ToSQL(), o.Values...)
34+
if err != nil {
35+
return nil, err
36+
}
37+
if len(o.children) > 0 {
38+
for _, v := range values {
39+
for _, childParser := range o.children {
40+
if data, err := childParser.GetData(); err != nil {
41+
return nil, err
42+
} else {
43+
v[childParser.Key] = data
44+
}
45+
}
46+
}
47+
}
48+
return values, nil
2949
}
30-
o.QueryFirst = true
31-
return o.parseObject(key, fieldMap)
50+
err := o.parseObject()
51+
if err != nil {
52+
return nil, err
53+
}
54+
sql := o.ToSQL()
55+
logger.Debugf("解析 %s 执行SQL: %s %v", o.Key, sql, o.Values)
56+
return QueryOne(sql, o.Values...), nil
3257
}
3358

34-
func (o *SQLParseObject) parseObject(key string, fieldMap map[string]interface{}) error {
35-
o.table = key
36-
for field, value := range fieldMap {
59+
func (o *SQLParser) parseObject() error {
60+
for field, value := range o.RequestMap {
3761
if value == nil {
3862
return fmt.Errorf("field value error, %s is nil", field)
3963
}
@@ -62,7 +86,7 @@ func (o *SQLParseObject) parseObject(key string, fieldMap map[string]interface{}
6286
return nil
6387
}
6488

65-
func (o *SQLParseObject) parseRangeCondition(field string, value interface{}) {
89+
func (o *SQLParser) parseRangeCondition(field string, value interface{}) {
6690
// 数组使用 IN 条件
6791
if values, ok := value.([]interface{}); ok {
6892
condition := field + " in ("
@@ -86,9 +110,9 @@ func (o *SQLParseObject) parseRangeCondition(field string, value interface{}) {
86110
}
87111
}
88112

89-
func (o *SQLParseObject) parseListQuery(fieldMap map[string]interface{}) error {
90-
91-
for field, value := range fieldMap {
113+
func (o *SQLParser) parseListQuery() error {
114+
o.table = o.Key[0 : len(o.Key)-2]
115+
for field, value := range o.RequestMap {
92116
if value == nil {
93117
return fmt.Errorf("field value error, %s is nil", field)
94118
}
@@ -101,7 +125,7 @@ func (o *SQLParseObject) parseListQuery(fieldMap map[string]interface{}) error {
101125
logger.Debugf("parseListQuery table:%s, size: %d", o.table, o.limit)
102126
default:
103127
if _, ok := AllTable[field]; ok {
104-
if err := o.parseObject(field, value.(map[string]interface{})); err != nil {
128+
if err := o.parseObject(); err != nil {
105129
return err
106130
}
107131
} else {
@@ -110,13 +134,13 @@ func (o *SQLParseObject) parseListQuery(fieldMap map[string]interface{}) error {
110134
}
111135
}
112136
if len(o.table) == 0 {
113-
return fmt.Errorf("请求列表数据处理失败,未发现可用表名 %v", fieldMap)
137+
return fmt.Errorf("请求列表数据处理失败,未发现可用表名 %v", o.RequestMap)
114138
}
115139
o.withPage = o.page > 0 && o.limit > 0
116140
return nil
117141
}
118142

119-
func (o *SQLParseObject) ToSQL() string {
143+
func (o *SQLParser) ToSQL() string {
120144
var buf bytes.Buffer
121145
buf.WriteString("SELECT ")
122146
if o.columns == nil {
@@ -134,7 +158,7 @@ func (o *SQLParseObject) ToSQL() string {
134158
buf.WriteString(" ORDER BY ")
135159
buf.WriteString(o.order)
136160
}
137-
if o.QueryFirst {
161+
if o.Key == o.table {
138162
buf.WriteString(" LIMIT 1")
139163
} else if o.withPage {
140164
buf.WriteString(" LIMIT ")

design.md

+32-1
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,35 @@ if rows.Next() {
8282
error: 39:1: expected '}', found 0 (and 10 more errors)
8383
```
8484

85-
这个报错也太简略了,翻了一下源码,感觉短时间里搞不定,还是自己写一个吧,挖个坑之后填,先把 0.0.1 的功能完成
85+
这个报错也太简略了,翻了一下源码,感觉短时间里搞不定,还是自己写一个吧,挖个坑之后填,先把 0.0.1 的功能完成
86+
87+
# 一些问题
88+
89+
在使用 Java 版的时候发现一个反直觉的点
90+
```json
91+
{
92+
"User":{
93+
"id": 93793
94+
},
95+
"[]": {
96+
"page": 0,
97+
"count": 3,
98+
"Moment": {
99+
"userId@": "User/id",
100+
"@column": "id,content,userId"
101+
},
102+
"list[]": {
103+
"count": 3,
104+
"Comment": {
105+
"momentId@": "[]/Moment/id"
106+
},
107+
"User": {
108+
"id@": "/Comment/userId"
109+
}
110+
}
111+
}
112+
}
113+
```
114+
上面 `"userId@": "User/id",` 查的是绝对路径,
115+
下面 `"id@": "/Comment/userId"` 查的却是相对路径,
116+
就 Linux 的使用习惯来说 `/` 在前表示的是绝对路径

handler/getHandler.go

+7-21
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@ func (c *SQLParseContext) getResponse() map[string]interface{} {
7070
}
7171
}
7272
}
73+
c.resp["code"] = http.StatusOK
7374
c.resp["time"] = fmt.Sprintf("%dms|%v", (time.Now().Nanosecond()-startTime)/1000000, c.time)
7475
return c.resp
7576
}
7677

7778
func (c *SQLParseContext) parseSQLAndGetResponse(key string) {
7879
startTime := time.Now().UnixNano()
79-
8080
c.waitKeys[key] = true
8181
logger.Debugf("开始解析 %s", key)
8282
if c.req[key] == nil {
@@ -86,34 +86,20 @@ func (c *SQLParseContext) parseSQLAndGetResponse(key string) {
8686
if fieldMap, ok := c.req[key].(map[string]interface{}); !ok {
8787
c.End(http.StatusBadRequest, "值类型不对,只支持 Object 类型")
8888
} else {
89-
parseObj := db.SQLParseObject{LoadFunc: c.queryResp}
90-
if c.end {
91-
return
92-
}
93-
if err := parseObj.From(key, fieldMap); err != nil {
94-
c.End(http.StatusBadRequest, err.Error())
95-
return
89+
obj := &db.SQLParser{Key: key, LoadFunc: c.queryResponse, RequestMap: fieldMap}
90+
value, err := obj.GetData()
91+
if err != nil {
92+
c.End(http.StatusInternalServerError, err.Error())
9693
} else {
97-
sql := parseObj.ToSQL()
98-
logger.Debugf("解析 %s 执行SQL: %s %v", key, sql, parseObj.Values)
99-
if parseObj.QueryFirst {
100-
c.resp[key], err = db.QueryOne(sql, parseObj.Values...)
101-
} else {
102-
c.resp[key], err = db.QueryAll(sql, parseObj.Values...)
103-
}
104-
if err != nil {
105-
c.End(http.StatusInternalServerError, err.Error())
106-
} else {
107-
c.resp["code"] = http.StatusOK
108-
}
94+
c.resp[key] = value
10995
}
11096
}
11197
c.waitKeys[key] = false
11298
c.time[key] = time.Now().UnixNano() - startTime
11399
}
114100

115101
// 查询已知结果
116-
func (c *SQLParseContext) queryResp(queryString string) interface{} {
102+
func (c *SQLParseContext) queryResponse(queryString string) interface{} {
117103
var paths []string
118104
qs := strings.TrimSpace(queryString)
119105
if strings.HasPrefix(qs, "/") {

0 commit comments

Comments
 (0)