add Walk function for package gset; improve fields handling feature for package gdb

This commit is contained in:
John
2020-04-27 21:18:42 +08:00
parent cf1d3d3d2b
commit 8d9dd17eac
8 changed files with 124 additions and 70 deletions

View File

@ -1,40 +1,25 @@
package main
import (
"fmt"
"time"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/gtimer"
"github.com/gogf/gf/util/gconv"
)
func main() {
s := g.Server()
s.SetDumpRouterMap(false)
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/", func(r *ghttp.Request) {
paramsMap := r.GetRequestMap()
fmt.Print("打印参数\n", paramsMap)
})
})
addr := "localhost:8199"
gtimer.SetTimeout(time.Second, func() {
client := g.Client().SetHeader("Content-Type", "application/x-www-form-urlencoded")
client.PostContent(
fmt.Sprintf("http://%s", addr),
"time_end2020-04-18 16:11:58&returnmsg=Success&attach=",
)
fmt.Print("\n")
client.PostContent(
fmt.Sprintf("http://%s", addr),
"returnmsg=Success&attach=",
)
})
s.SetAddr(addr)
s.Run()
type SaveReq1 struct {
Id uint
Tags string
}
type SaveReq2 struct {
Id uint
Tags []string
}
r1 := SaveReq1{
Id: 1,
Tags: "ac",
}
var r2 *SaveReq2
err := gconv.Struct(r1, &r2)
g.Dump(err)
g.Dump(r2)
}

View File

@ -452,6 +452,16 @@ func (set *Set) Pops(size int) []interface{} {
return array
}
// Walk applies a user supplied function <f> to every item of set.
func (set *Set) Walk(f func(item interface{}) interface{}) *Set {
set.mu.Lock()
defer set.mu.Unlock()
for k, v := range set.data {
set.data[f(k)] = v
}
return set
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (set *Set) MarshalJSON() ([]byte, error) {
return json.Marshal(set.Slice())

View File

@ -412,6 +412,16 @@ func (set *IntSet) Pops(size int) []int {
return array
}
// Walk applies a user supplied function <f> to every item of set.
func (set *IntSet) Walk(f func(item int) int) *IntSet {
set.mu.Lock()
defer set.mu.Unlock()
for k, v := range set.data {
set.data[f(k)] = v
}
return set
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (set *IntSet) MarshalJSON() ([]byte, error) {
return json.Marshal(set.Slice())

View File

@ -426,6 +426,16 @@ func (set *StrSet) Pops(size int) []string {
return array
}
// Walk applies a user supplied function <f> to every item of set.
func (set *StrSet) Walk(f func(item string) string) *StrSet {
set.mu.Lock()
defer set.mu.Unlock()
for k, v := range set.data {
set.data[f(k)] = v
}
return set
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (set *StrSet) MarshalJSON() ([]byte, error) {
return json.Marshal(set.Slice())

View File

@ -83,12 +83,15 @@ func (d *DriverMysql) Tables(schema ...string) (tables []string, err error) {
return
}
// TableFields retrieves and returns the fields information of specified table of current schema.
// TableFields retrieves and returns the fields information of specified table of current
// schema.
//
// Note that it returns a map containing the field name and its corresponding fields.
// As a map is unsorted, the TableField struct has a "Index" field marks its sequence in the fields.
// As a map is unsorted, the TableField struct has a "Index" field marks its sequence in
// the fields.
//
// It's using cache feature to enhance the performance, which is never expired util the process restarts.
// It's using cache feature to enhance the performance, which is never expired util the
// process restarts.
func (d *DriverMysql) TableFields(table string, schema ...string) (fields map[string]*TableField, err error) {
charL, charR := d.GetChars()
table = gstr.Trim(table, charL+charR)

View File

@ -7,7 +7,7 @@
package gdb
import (
"github.com/gogf/gf/container/garray"
"fmt"
"github.com/gogf/gf/container/gset"
"github.com/gogf/gf/text/gstr"
)
@ -34,21 +34,31 @@ func (m *Model) FieldsEx(fields string) *Model {
if gstr.Contains(m.tables, " ") {
panic("function FieldsEx supports only single table operations")
}
tableFields, err := m.db.TableFields(m.tables)
if err != nil {
panic(err)
}
if len(tableFields) == 0 {
panic(fmt.Sprintf(`empty table fields for table "%s"`, m.tables))
}
model := m.getModel()
model.fieldsEx = fields
fieldsExSet := gset.NewStrSetFrom(gstr.SplitAndTrim(fields, ","))
if m, err := m.db.TableFields(m.tables); err == nil {
model.fields = ""
for k, _ := range m {
if fieldsExSet.Contains(k) {
continue
}
if len(model.fields) > 0 {
model.fields += ","
}
model.fields += k
}
fieldsArray := make([]string, len(tableFields))
for k, v := range tableFields {
fieldsArray[v.Index] = k
}
model.fields = ""
for _, k := range fieldsArray {
if fieldsExSet.Contains(k) {
continue
}
if len(model.fields) > 0 {
model.fields += ","
}
model.fields += k
}
model.fields = model.db.QuoteString(model.fields)
return model
}
@ -59,14 +69,26 @@ func (m *Model) FieldsStr(prefix ...string) string {
if len(prefix) > 0 {
prefixStr = prefix[0]
}
if m, err := m.db.TableFields(m.tables); err == nil {
fieldsArray := garray.NewStrArraySize(len(m), len(m))
for _, field := range m {
fieldsArray.Set(field.Index, prefixStr+field.Name)
}
return fieldsArray.Join(",")
tableFields, err := m.db.TableFields(m.tables)
if err != nil {
panic(err)
}
return ""
if len(tableFields) == 0 {
panic(fmt.Sprintf(`empty table fields for table "%s"`, m.tables))
}
fieldsArray := make([]string, len(tableFields))
for k, v := range tableFields {
fieldsArray[v.Index] = k
}
newFields := ""
for _, k := range fieldsArray {
if len(newFields) > 0 {
newFields += ","
}
newFields += prefixStr + k
}
newFields = m.db.QuoteString(newFields)
return newFields
}
// FieldsExStr retrieves and returns fields which are not in parameter <fields> from the table,
@ -78,17 +100,28 @@ func (m *Model) FieldsExStr(fields string, prefix ...string) string {
if len(prefix) > 0 {
prefixStr = prefix[0]
}
if m, err := m.db.TableFields(m.tables); err == nil {
fieldsArray := garray.NewStrArraySize(len(m), len(m))
fieldsExSet := gset.NewStrSetFrom(gstr.SplitAndTrim(fields, ","))
for _, field := range m {
if fieldsExSet.Contains(field.Name) {
continue
}
fieldsArray.Set(field.Index, prefixStr+field.Name)
}
fieldsArray.FilterEmpty()
return fieldsArray.Join(",")
tableFields, err := m.db.TableFields(m.tables)
if err != nil {
panic(err)
}
return ""
if len(tableFields) == 0 {
panic(fmt.Sprintf(`empty table fields for table "%s"`, m.tables))
}
fieldsExSet := gset.NewStrSetFrom(gstr.SplitAndTrim(fields, ","))
fieldsArray := make([]string, len(tableFields))
for k, v := range tableFields {
fieldsArray[v.Index] = k
}
newFields := ""
for _, k := range fieldsArray {
if fieldsExSet.Contains(k) {
continue
}
if len(newFields) > 0 {
newFields += ","
}
newFields += prefixStr + k
}
newFields = m.db.QuoteString(newFields)
return newFields
}

View File

@ -80,6 +80,9 @@ func (m *Model) doFilterDataMapForInsertOrUpdate(data Map, allowOmitEmpty bool)
charL, charR = m.db.GetChars()
chars = charL + charR
)
set.Walk(func(item string) string {
return gstr.Trim(item, chars)
})
for k := range data {
k = gstr.Trim(k, chars)
if !set.Contains(k) {

View File

@ -1870,8 +1870,8 @@ func Test_Model_FieldsStr(t *testing.T) {
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
t.Assert(db.Table(table).FieldsStr(), "id,passport,password,nickname,create_time")
t.Assert(db.Table(table).FieldsStr("a."), "a.id,a.passport,a.password,a.nickname,a.create_time")
t.Assert(db.Table(table).FieldsStr(), "`id`,`passport`,`password`,`nickname`,`create_time`")
t.Assert(db.Table(table).FieldsStr("a."), "`a`.`id`,`a`.`passport`,`a`.`password`,`a`.`nickname`,`a`.`create_time`")
})
}
@ -1880,8 +1880,8 @@ func Test_Model_FieldsExStr(t *testing.T) {
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
t.Assert(db.Table(table).FieldsExStr("create_time,nickname"), "id,passport,password")
t.Assert(db.Table(table).FieldsExStr("create_time,nickname", "a."), "a.id,a.passport,a.password")
t.Assert(db.Table(table).FieldsExStr("create_time,nickname"), "`id`,`passport`,`password`")
t.Assert(db.Table(table).FieldsExStr("create_time,nickname", "a."), "`a`.`id`,`a`.`passport`,`a`.`password`")
})
}