mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
add Walk function for package gset; improve fields handling feature for package gdb
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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`")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user