Compare commits

..

5 Commits

50 changed files with 331 additions and 167 deletions

View File

@ -7,20 +7,21 @@
package gfcmd
import (
_ "github.com/gogf/gf/cmd/gf/v2/internal/packed"
"context"
"runtime"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"context"
"github.com/gogf/gf/cmd/gf/v2/internal/cmd"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/allyes"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcfg"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/cmd/gf/v2/internal/cmd"
_ "github.com/gogf/gf/cmd/gf/v2/internal/packed"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/allyes"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
)
const (
@ -99,6 +100,9 @@ func GetCommand(ctx context.Context) (*Command, error) {
// zsh alias "git fetch" conflicts checks.
func handleZshAlias() {
if runtime.GOOS == "windows" {
return
}
if home, err := gfile.Home(); err == nil {
zshPath := gfile.Join(home, ".zshrc")
if gfile.Exists(zshPath) {

View File

@ -3,13 +3,13 @@ module github.com/gogf/gf/cmd/gf/v2
go 1.18
require (
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.5.7
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.6.0-beta
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.6.0-beta
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.0-beta
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.6.0-beta
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.6.0-beta
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.6.0-beta
github.com/gogf/gf/v2 v2.6.0-beta
github.com/minio/selfupdate v0.6.0
github.com/olekukonko/tablewriter v0.0.5
golang.org/x/mod v0.9.0

View File

@ -38,20 +38,6 @@ github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.5.6 h1:yziPSf9AycEWphv9WiNjcRAVPOJtUauMMvP6pHQB4jY=
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.5.6/go.mod h1:yOlpwhFXgW+P2sf4goA20PUtxdVLliBx4dJRyJeOtto=
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.5.6 h1:LGQIe5IvYVr4hZ/vUAFiqWssxE7QeILyVPJ9swo1Cmk=
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.5.6/go.mod h1:EcF8v8jqCV61/YqN6DXxdo3kh8waGmEj6WpFqbLkkrM=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.6 h1:oR9F4LVoKa/fjf/o6Y/CQRNiYy35Bszo07WwvMWYMxo=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.6/go.mod h1:gvHSRqCpv2c+N0gDHsEldHgU/yM9tcCBdIEKZ32/TaE=
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.5.6 h1:3Y3lEoO9SoG1AmfaKjgTsDt93+T2q/qTMog8wBvIIGM=
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.5.6/go.mod h1:cR3lFoU6ZtSaMQ3DpCJwWnYW6EvHPYGGeqv/kzgH4gw=
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.5.6 h1:0WHVzqITqIBu/NNPXt3tN2eiWAGiNjs9sg6wh+WbUvY=
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.5.6/go.mod h1:qZCTNQ0n2gHcuBwM9wUl3pelync3xK0gTnChJZD6f0I=
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.5.6 h1:6clfLvFoHXHdw+skmXg4yxw+cLwgAG8gRiS/6f9Y9Xc=
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.5.6/go.mod h1:QV6Rrj+4G4OaJVkP9XXRZ1LWL+ls6qH7ebeMcxsulqA=
github.com/gogf/gf/v2 v2.5.6 h1:a1UK1yUP3s+l+vPxmV91+8gTarAP9b1IEOw0W7LNl6E=
github.com/gogf/gf/v2 v2.5.6/go.mod h1:17K/gBYrp0bHGC3XYC7bSPoywmZ6MrZHrZakTfh4eIQ=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=

View File

@ -82,11 +82,11 @@ func init() {
type (
cRunInput struct {
g.Meta `name:"run"`
File string `name:"FILE" arg:"true" brief:"{cRunFileBrief}" v:"required"`
Path string `name:"path" short:"p" brief:"{cRunPathBrief}" d:"./"`
Extra string `name:"extra" short:"e" brief:"{cRunExtraBrief}"`
Args string `name:"args" short:"a" brief:"{cRunArgsBrief}"`
WatchPaths string `name:"watchPaths" short:"w" brief:"{cRunWatchPathsBrief}"`
File string `name:"FILE" arg:"true" brief:"{cRunFileBrief}" v:"required"`
Path string `name:"path" short:"p" brief:"{cRunPathBrief}" d:"./"`
Extra string `name:"extra" short:"e" brief:"{cRunExtraBrief}"`
Args string `name:"args" short:"a" brief:"{cRunArgsBrief}"`
WatchPaths []string `name:"watchPaths" short:"w" brief:"{cRunWatchPathsBrief}"`
}
cRunOutput struct{}
)
@ -97,12 +97,16 @@ func (c cRun) Index(ctx context.Context, in cRunInput) (out *cRunOutput, err err
mlog.Fatalf(`command "go" not found in your environment, please install golang first to proceed this command`)
}
if len(in.WatchPaths) == 1 {
in.WatchPaths = strings.Split(in.WatchPaths[0], ",")
}
app := &cRunApp{
File: in.File,
Path: in.Path,
Options: in.Extra,
Args: in.Args,
WatchPaths: strings.Split(in.WatchPaths, ","),
WatchPaths: in.WatchPaths,
}
dirty := gtype.NewBool()
_, err = gfsnotify.Add(gfile.RealPath("."), func(event *gfsnotify.Event) {

View File

@ -74,7 +74,7 @@ type (
SdkStdVersion bool `short:"v" name:"sdkStdVersion" brief:"{CGenCtrlBriefSdkStdVersion}" orphan:"true"`
SdkNoV1 bool `short:"n" name:"sdkNoV1" brief:"{CGenCtrlBriefSdkNoV1}" orphan:"true"`
Clear bool `short:"c" name:"clear" brief:"{CGenCtrlBriefClear}" orphan:"true"`
Merge bool `short:"m" name:"merge" brief:"{CGenCtrlControllerMerge}" orphan:"true"`
Merge bool `short:"m" name:"merge" brief:"{CGenCtrlControllerMerge}" orphan:"true"`
}
CGenCtrlOutput struct{}
)

View File

@ -24,15 +24,19 @@ var (
)
func init() {
logger.SetStack(false)
if genv.Get(headerPrintEnvName).String() == "1" {
logger.SetHeaderPrint(true)
} else {
logger.SetHeaderPrint(false)
}
if gcmd.GetOpt("debug") != nil || gcmd.GetOpt("gf.debug") != nil {
logger.SetHeaderPrint(true)
logger.SetStackSkip(4)
logger.SetFlags(logger.GetFlags() | glog.F_FILE_LONG)
logger.SetDebug(true)
} else {
logger.SetStack(false)
logger.SetDebug(false)
}
}

View File

@ -8,24 +8,27 @@ package gvar
import "github.com/gogf/gf/v2/util/gconv"
// MapOption specifies the option for map converting.
type MapOption = gconv.MapOption
// Map converts and returns `v` as map[string]interface{}.
func (v *Var) Map(tags ...string) map[string]interface{} {
return gconv.Map(v.Val(), tags...)
func (v *Var) Map(option ...MapOption) map[string]interface{} {
return gconv.Map(v.Val(), option...)
}
// MapStrAny is like function Map, but implements the interface of MapStrAny.
func (v *Var) MapStrAny() map[string]interface{} {
return v.Map()
func (v *Var) MapStrAny(option ...MapOption) map[string]interface{} {
return v.Map(option...)
}
// MapStrStr converts and returns `v` as map[string]string.
func (v *Var) MapStrStr(tags ...string) map[string]string {
return gconv.MapStrStr(v.Val(), tags...)
func (v *Var) MapStrStr(option ...MapOption) map[string]string {
return gconv.MapStrStr(v.Val(), option...)
}
// MapStrVar converts and returns `v` as map[string]Var.
func (v *Var) MapStrVar(tags ...string) map[string]*Var {
m := v.Map(tags...)
func (v *Var) MapStrVar(option ...MapOption) map[string]*Var {
m := v.Map(option...)
if len(m) > 0 {
vMap := make(map[string]*Var, len(m))
for k, v := range m {
@ -37,16 +40,19 @@ func (v *Var) MapStrVar(tags ...string) map[string]*Var {
}
// MapDeep converts and returns `v` as map[string]interface{} recursively.
// Deprecated: used Map instead.
func (v *Var) MapDeep(tags ...string) map[string]interface{} {
return gconv.MapDeep(v.Val(), tags...)
}
// MapStrStrDeep converts and returns `v` as map[string]string recursively.
// Deprecated: used MapStrStr instead.
func (v *Var) MapStrStrDeep(tags ...string) map[string]string {
return gconv.MapStrStrDeep(v.Val(), tags...)
}
// MapStrVarDeep converts and returns `v` as map[string]*Var recursively.
// Deprecated: used MapStrVar instead.
func (v *Var) MapStrVarDeep(tags ...string) map[string]*Var {
m := v.MapDeep(tags...)
if len(m) > 0 {
@ -61,12 +67,12 @@ func (v *Var) MapStrVarDeep(tags ...string) map[string]*Var {
// Maps converts and returns `v` as map[string]string.
// See gconv.Maps.
func (v *Var) Maps(tags ...string) []map[string]interface{} {
return gconv.Maps(v.Val(), tags...)
func (v *Var) Maps(option ...MapOption) []map[string]interface{} {
return gconv.Maps(v.Val(), option...)
}
// MapsDeep converts `value` to []map[string]interface{} recursively.
// See gconv.MapsDeep.
// Deprecated: used Maps instead.
func (v *Var) MapsDeep(tags ...string) []map[string]interface{} {
return gconv.MapsDeep(v.Val(), tags...)
}

View File

@ -4,7 +4,7 @@ go 1.18
require (
github.com/apolloconfig/agollo/v4 v4.3.1
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
)
require (

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/consul/v2
go 1.19
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/hashicorp/consul/api v1.24.0
github.com/hashicorp/go-cleanhttp v0.5.2
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/kubecm/v2
go 1.19
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
k8s.io/api v0.27.4
k8s.io/apimachinery v0.27.4
k8s.io/client-go v0.27.4

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/nacos/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/nacos-group/nacos-sdk-go v1.1.4
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/polaris/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/polarismesh/polaris-go v1.5.5
)

View File

@ -4,7 +4,7 @@ go 1.18
require (
github.com/ClickHouse/clickhouse-go/v2 v2.0.15
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/google/uuid v1.3.0
github.com/shopspring/decimal v1.3.1
)

View File

@ -6,7 +6,7 @@ replace github.com/gogf/gf/v2 => ../../../
require (
gitee.com/chunanyong/dm v1.8.12
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
)
require (

View File

@ -4,7 +4,7 @@ go 1.18
require (
github.com/denisenkom/go-mssqldb v0.12.3
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
)
require (

View File

@ -4,7 +4,7 @@ go 1.18
require (
github.com/go-sql-driver/mysql v1.7.1
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
)
require (

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/drivers/oracle/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/sijms/go-ora/v2 v2.7.10
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/drivers/pgsql/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/lib/pq v1.10.9
)

View File

@ -15,6 +15,7 @@ import (
"context"
"database/sql"
"fmt"
"regexp"
"strings"
_ "github.com/lib/pq"
@ -237,6 +238,12 @@ func (d *Driver) Tables(ctx context.Context, schema ...string) (tables []string,
if err != nil {
return nil, err
}
useRelpartbound := ""
if gstr.CompareVersion(d.version(ctx, link), "10") >= 0 {
useRelpartbound = "AND c.relpartbound IS NULL"
}
var query = fmt.Sprintf(`
SELECT
c.relname
@ -247,10 +254,11 @@ INNER JOIN pg_namespace n ON
WHERE
n.nspname = '%s'
AND c.relkind IN ('r', 'p')
AND c.relpartbound IS NULL
%s
ORDER BY
c.relname`,
usedSchema,
useRelpartbound,
)
query, _ = gregex.ReplaceString(`[\n\r\s]+`, " ", gstr.Trim(query))
@ -266,6 +274,23 @@ ORDER BY
return
}
// version checks and returns the database version.
func (d *Driver) version(ctx context.Context, link gdb.Link) string {
result, err := d.DoSelect(ctx, link, "SELECT version();")
if err != nil {
return ""
}
if len(result) > 0 {
if v, ok := result[0]["version"]; ok {
matches := regexp.MustCompile(`PostgreSQL (\d+\.\d+)`).FindStringSubmatch(v.String())
if len(matches) >= 2 {
return matches[1]
}
}
}
return ""
}
// TableFields retrieves and returns the fields' information of specified table of current schema.
func (d *Driver) TableFields(ctx context.Context, table string, schema ...string) (fields map[string]*gdb.TableField, err error) {
var (

View File

@ -4,7 +4,7 @@ go 1.18
require (
github.com/glebarez/go-sqlite v1.21.2
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
)
require (

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/drivers/sqlitecgo/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/mattn/go-sqlite3 v1.14.17
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/nosql/redis/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/redis/go-redis/v9 v9.2.1
go.opentelemetry.io/otel v1.14.0
go.opentelemetry.io/otel/trace v1.14.0

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/etcd/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
go.etcd.io/etcd/client/v3 v3.5.7
)

View File

@ -2,7 +2,7 @@ module github.com/gogf/gf/contrib/registry/file/v2
go 1.18
require github.com/gogf/gf/v2 v2.5.7
require github.com/gogf/gf/v2 v2.6.0-beta
require (
github.com/BurntSushi/toml v1.2.0 // indirect

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/nacos/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/joy999/nacos-sdk-go v0.0.0-20231120071639-10a34b3e7288
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/polaris/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
github.com/polarismesh/polaris-go v1.5.5
)

View File

@ -4,7 +4,7 @@ go 1.18
require (
github.com/go-zookeeper/zk v1.0.3
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
golang.org/x/sync v0.4.0
)

View File

@ -3,8 +3,8 @@ module github.com/gogf/gf/contrib/rpc/grpcx/v2
go 1.18
require (
github.com/gogf/gf/contrib/registry/file/v2 v2.5.7
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/contrib/registry/file/v2 v2.6.0-beta
github.com/gogf/gf/v2 v2.6.0-beta
go.opentelemetry.io/otel v1.14.0
go.opentelemetry.io/otel/trace v1.14.0
google.golang.org/grpc v1.57.2

View File

@ -8,7 +8,6 @@ package grpcx
import (
"context"
"google.golang.org/grpc"
"github.com/gogf/gf/v2/frame/g"
@ -18,18 +17,41 @@ import (
// GrpcServerConfig is the configuration for server.
type GrpcServerConfig struct {
Address string // (optional) Single address for server listening, use `:0` or `ip:0` to serve random port.
Name string // (optional) Name for current service.
Logger *glog.Logger // (optional) Logger for server.
LogPath string // (optional) LogPath specifies the directory for storing logging files.
LogStdout bool // (optional) LogStdout specifies whether printing logging content to stdout.
ErrorStack bool // (optional) ErrorStack specifies whether logging stack information when error.
ErrorLogEnabled bool // (optional) ErrorLogEnabled enables error logging content to files.
ErrorLogPattern string // (optional) ErrorLogPattern specifies the error log file pattern like: error-{Ymd}.log
AccessLogEnabled bool // (optional) AccessLogEnabled enables access logging content to file.
AccessLogPattern string // (optional) AccessLogPattern specifies the error log file pattern like: access-{Ymd}.log
Endpoints []string // (optional) Endpoints are custom endpoints for service register, it uses Address if empty.
Options []grpc.ServerOption // (optional) GRPC Server options.
// (optional) Name for current service.
Name string
// (optional) Single address for server listening, use `:0` or `ip:0` to serve random port.
Address string
// (optional) Logger for server.
Logger *glog.Logger
// (optional) LogPath specifies the directory for storing logging files.
LogPath string
// (optional) LogStdout specifies whether printing logging content to stdout.
LogStdout bool
// (optional) ErrorStack specifies whether logging stack information when error.
ErrorStack bool
// (optional) ErrorLogEnabled enables error logging content to files.
ErrorLogEnabled bool
// (optional) ErrorLogPattern specifies the error log file pattern like: error-{Ymd}.log
ErrorLogPattern string
// (optional) AccessLogEnabled enables access logging content to file.
AccessLogEnabled bool
// (optional) AccessLogPattern specifies the error log file pattern like: access-{Ymd}.log
AccessLogPattern string
// (optional) Endpoints are custom endpoints for service register, it uses Address if empty.
Endpoints []string
// (optional) GRPC Server options.
Options []grpc.ServerOption
}
// NewConfig creates and returns a ServerConfig object with default configurations.
@ -51,6 +73,7 @@ func (s modServer) NewConfig() *GrpcServerConfig {
)
// Reading configuration file and updating the configured keys.
if g.Cfg().Available(ctx) {
// Server attributes configuration.
if err = g.Cfg().MustGet(ctx, configNodeNameGrpcServer).Struct(&config); err != nil {
g.Log().Error(ctx, err)
}

View File

@ -2,7 +2,7 @@ module github.com/gogf/gf/contrib/sdk/httpclient/v2
go 1.18
require github.com/gogf/gf/v2 v2.5.7
require github.com/gogf/gf/v2 v2.6.0-beta
require (
github.com/BurntSushi/toml v1.2.0 // indirect

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/trace/jaeger/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
go.opentelemetry.io/otel v1.14.0
go.opentelemetry.io/otel/exporters/jaeger v1.14.0
go.opentelemetry.io/otel/sdk v1.14.0

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/trace/otlpgrpc/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
go.opentelemetry.io/otel v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/trace/otlphttp/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/v2 v2.6.0-beta
go.opentelemetry.io/otel v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0

View File

@ -210,14 +210,14 @@ func GetInsertOperationByOption(option InsertOption) string {
}
func anyValueToMapBeforeToRecord(value interface{}) map[string]interface{} {
return gconv.Map(value, structTagPriority...)
return gconv.Map(value, gconv.MapOption{Tags: structTagPriority})
}
// DataToMapDeep converts `value` to map type recursively(if attribute struct is embedded).
// The parameter `value` should be type of *map/map/*struct/struct.
// It supports embedded struct definition for struct.
func DataToMapDeep(value interface{}) map[string]interface{} {
m := gconv.Map(value, structTagPriority...)
m := gconv.Map(value, gconv.MapOption{Tags: structTagPriority})
for k, v := range m {
switch v.(type) {
case time.Time, *time.Time, gtime.Time, *gtime.Time, gjson.Json, *gjson.Json:

View File

@ -16,9 +16,9 @@ type Option struct {
Code gcode.Code // Error code if necessary.
}
// NewOption creates and returns a custom error with Option.
// NewWithOption creates and returns a custom error with Option.
// It is the senior usage for creating error, which is often used internally in framework.
func NewOption(option Option) error {
func NewWithOption(option Option) error {
err := &Error{
error: option.Error,
text: option.Text,
@ -29,3 +29,9 @@ func NewOption(option Option) error {
}
return err
}
// NewOption creates and returns a custom error with Option.
// Deprecated: use NewWithOption instead.
func NewOption(option Option) error {
return NewWithOption(option)
}

View File

@ -442,7 +442,7 @@ func Test_HashCode(t *testing.T) {
func Test_NewOption(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
t.AssertNE(gerror.NewOption(gerror.Option{
t.AssertNE(gerror.NewWithOption(gerror.Option{
Error: errors.New("NewOptionError"),
Stack: true,
Text: "Text",

View File

@ -3,21 +3,21 @@ module github.com/gogf/gf/example
go 1.20
require (
github.com/gogf/gf/contrib/config/apollo/v2 v2.5.7
github.com/gogf/gf/contrib/config/consul/v2 v2.5.7
github.com/gogf/gf/contrib/config/kubecm/v2 v2.5.7
github.com/gogf/gf/contrib/config/nacos/v2 v2.5.7
github.com/gogf/gf/contrib/config/polaris/v2 v2.5.7
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.7
github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.7
github.com/gogf/gf/contrib/registry/etcd/v2 v2.5.7
github.com/gogf/gf/contrib/registry/file/v2 v2.5.7
github.com/gogf/gf/contrib/config/apollo/v2 v2.6.0-beta
github.com/gogf/gf/contrib/config/consul/v2 v2.6.0-beta
github.com/gogf/gf/contrib/config/kubecm/v2 v2.6.0-beta
github.com/gogf/gf/contrib/config/nacos/v2 v2.6.0-beta
github.com/gogf/gf/contrib/config/polaris/v2 v2.6.0-beta
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.0-beta
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.0-beta
github.com/gogf/gf/contrib/registry/etcd/v2 v2.6.0-beta
github.com/gogf/gf/contrib/registry/file/v2 v2.6.0-beta
github.com/gogf/gf/contrib/registry/nacos/v2 v2.5.6
github.com/gogf/gf/contrib/registry/polaris/v2 v2.5.7
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.5.7
github.com/gogf/gf/contrib/trace/otlpgrpc/v2 v2.5.7
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.5.7
github.com/gogf/gf/v2 v2.5.7
github.com/gogf/gf/contrib/registry/polaris/v2 v2.6.0-beta
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.6.0-beta
github.com/gogf/gf/contrib/trace/otlpgrpc/v2 v2.6.0-beta
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.6.0-beta
github.com/gogf/gf/v2 v2.6.0-beta
github.com/hashicorp/consul/api v1.24.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/nacos-group/nacos-sdk-go v1.1.4

View File

@ -205,7 +205,7 @@ var (
)
var (
ErrNeedJsonBody = gerror.NewOption(gerror.Option{
ErrNeedJsonBody = gerror.NewWithOption(gerror.Option{
Text: "the request body content should be JSON format",
Code: gcode.CodeInvalidRequest,
})

View File

@ -11,6 +11,7 @@ import (
"os"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcfg"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/genv"
@ -64,3 +65,21 @@ func ExampleConfig_GetWithCmd() {
// cmd:
// cmd:yes
}
func Example_NewWithAdapter() {
var (
ctx = gctx.New()
content = `{"a":"b", "c":1}`
adapter, err = gcfg.NewAdapterContent(content)
)
if err != nil {
panic(err)
}
config := gcfg.NewWithAdapter(adapter)
fmt.Println(config.MustGet(ctx, "a"))
fmt.Println(config.MustGet(ctx, "c"))
// Output:
// b
// 1
}

View File

@ -219,8 +219,8 @@ func (l *Logger) print(ctx context.Context, level int, stack string, values ...a
}
}
// doDefaultPrint outputs the logging content according configuration.
func (l *Logger) doDefaultPrint(ctx context.Context, input *HandlerInput) *bytes.Buffer {
// doFinalPrint outputs the logging content according configuration.
func (l *Logger) doFinalPrint(ctx context.Context, input *HandlerInput) *bytes.Buffer {
var buffer *bytes.Buffer
// Allow output to stdout?
if l.config.StdoutPrint {

View File

@ -49,7 +49,7 @@ var defaultHandler Handler
// doFinalPrint is a handler for logging content printing.
// This handler outputs logging content to file/stdout/write if any of them configured.
func doFinalPrint(ctx context.Context, in *HandlerInput) {
buffer := in.Logger.doDefaultPrint(ctx, in)
buffer := in.Logger.doFinalPrint(ctx, in)
if in.Buffer.Len() == 0 {
in.Buffer = buffer
}

View File

@ -15,7 +15,7 @@ import (
var (
// ErrorDisabled is used for marking certain interface function not used.
ErrorDisabled = gerror.NewOption(gerror.Option{
ErrorDisabled = gerror.NewWithOption(gerror.Option{
Text: "this feature is disabled in this storage",
Code: gcode.CodeNotSupported,
})

View File

@ -22,40 +22,57 @@ const (
recursiveTypeTrue recursiveType = "true"
)
// MapOption specifies the option for map converting.
type MapOption struct {
// Deep marks doing Map function recursively, which means if the attribute of given converting value
// is also a struct/*struct, it automatically calls Map function on this attribute converting it to
// a map[string]interface{} type variable.
Deep bool
// OmitEmpty ignores the attributes that has json omitempty tag.
OmitEmpty bool
// Tags specifies the converted map key name by struct tag name.
Tags []string
}
// Map converts any variable `value` to map[string]interface{}. If the parameter `value` is not a
// map/struct/*struct type, then the conversion will fail and returns nil.
//
// If `value` is a struct/*struct object, the second parameter `tags` specifies the most priority
// tags that will be detected, otherwise it detects the tags in order of:
// gconv, json, field name.
func Map(value interface{}, tags ...string) map[string]interface{} {
return doMapConvert(value, recursiveTypeAuto, false, tags...)
func Map(value interface{}, option ...MapOption) map[string]interface{} {
return doMapConvert(value, recursiveTypeAuto, false, option...)
}
// MapDeep does Map function recursively, which means if the attribute of `value`
// is also a struct/*struct, calls Map function on this attribute converting it to
// a map[string]interface{} type variable.
// Also see Map.
// Deprecated: used Map instead.
func MapDeep(value interface{}, tags ...string) map[string]interface{} {
return doMapConvert(value, recursiveTypeTrue, false, tags...)
return doMapConvert(value, recursiveTypeTrue, false, MapOption{
Tags: tags,
})
}
// doMapConvert implements the map converting.
// It automatically checks and converts json string to map if `value` is string/[]byte.
//
// TODO completely implement the recursive converting for all types, especially the map.
func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool, tags ...string) map[string]interface{} {
func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool, option ...MapOption) map[string]interface{} {
if value == nil {
return nil
}
var usedOption = getUsedMapOption(option...)
newTags := StructTagPriority
switch len(tags) {
switch len(usedOption.Tags) {
case 0:
// No need handling.
case 1:
newTags = append(strings.Split(tags[0], ","), StructTagPriority...)
newTags = append(strings.Split(usedOption.Tags[0], ","), StructTagPriority...)
default:
newTags = append(tags, StructTagPriority...)
newTags = append(usedOption.Tags, StructTagPriority...)
}
// Assert the common combination of types, and finally it uses reflection.
dataMap := make(map[string]interface{})
@ -79,6 +96,8 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
return nil
}
case map[interface{}]interface{}:
recursiveOption := usedOption
recursiveOption.Tags = newTags
for k, v := range r {
dataMap[String(k)] = doMapConvertForMapOrStructValue(
doMapConvertForMapOrStructValueInput{
@ -86,7 +105,7 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
Value: v,
RecursiveType: recursive,
RecursiveOption: recursive == recursiveTypeTrue,
Tags: newTags,
Option: recursiveOption,
},
)
}
@ -136,6 +155,8 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
}
case map[string]interface{}:
if recursive == recursiveTypeTrue {
recursiveOption := usedOption
recursiveOption.Tags = newTags
// A copy of current map.
for k, v := range r {
dataMap[k] = doMapConvertForMapOrStructValue(
@ -144,7 +165,7 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
Value: v,
RecursiveType: recursive,
RecursiveOption: recursive == recursiveTypeTrue,
Tags: newTags,
Option: recursiveOption,
},
)
}
@ -153,6 +174,8 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
return r
}
case map[int]interface{}:
recursiveOption := usedOption
recursiveOption.Tags = newTags
for k, v := range r {
dataMap[String(k)] = doMapConvertForMapOrStructValue(
doMapConvertForMapOrStructValueInput{
@ -160,7 +183,7 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
Value: v,
RecursiveType: recursive,
RecursiveOption: recursive == recursiveTypeTrue,
Tags: newTags,
Option: recursiveOption,
},
)
}
@ -202,13 +225,15 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
}
}
case reflect.Map, reflect.Struct, reflect.Interface:
recursiveOption := usedOption
recursiveOption.Tags = newTags
convertedValue := doMapConvertForMapOrStructValue(
doMapConvertForMapOrStructValueInput{
IsRoot: true,
Value: value,
RecursiveType: recursive,
RecursiveOption: recursive == recursiveTypeTrue,
Tags: newTags,
Option: recursiveOption,
MustMapReturn: mustMapReturn,
},
)
@ -223,12 +248,20 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
return dataMap
}
func getUsedMapOption(option ...MapOption) MapOption {
var usedOption MapOption
if len(option) > 0 {
usedOption = option[0]
}
return usedOption
}
type doMapConvertForMapOrStructValueInput struct {
IsRoot bool // It returns directly if it is not root and with no recursive converting.
Value interface{} // Current operation value.
RecursiveType recursiveType // The type from top function entry.
RecursiveOption bool // Whether convert recursively for `current` operation.
Tags []string // Map key mapping.
Option MapOption // Map converting option.
MustMapReturn bool // Must return map instead of Value when empty.
}
@ -280,7 +313,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: mapValue,
RecursiveType: in.RecursiveType,
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
Tags: in.Tags,
Option: in.Option,
},
)
}
@ -299,7 +332,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: mapV,
RecursiveType: in.RecursiveType,
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
Tags: in.Tags,
Option: in.Option,
},
)
} else {
@ -327,7 +360,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
}
mapKey = ""
fieldTag := rtField.Tag
for _, tag := range in.Tags {
for _, tag := range in.Option.Tags {
if mapKey = fieldTag.Get(tag); mapKey != "" {
break
}
@ -344,7 +377,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
if len(array) > 1 {
switch strings.TrimSpace(array[1]) {
case "omitempty":
if empty.IsEmpty(rvField.Interface()) {
if in.Option.OmitEmpty && empty.IsEmpty(rvField.Interface()) {
continue
} else {
mapKey = strings.TrimSpace(array[0])
@ -389,7 +422,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: rvInterface,
RecursiveType: in.RecursiveType,
RecursiveOption: true,
Tags: in.Tags,
Option: in.Option,
})
if m, ok := anonymousValue.(map[string]interface{}); ok {
for k, v := range m {
@ -406,7 +439,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: rvInterface,
RecursiveType: in.RecursiveType,
RecursiveOption: true,
Tags: in.Tags,
Option: in.Option,
})
default:
@ -415,7 +448,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: rvInterface,
RecursiveType: in.RecursiveType,
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
Tags: in.Tags,
Option: in.Option,
})
}
@ -434,7 +467,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: rvAttrField.Index(arrayIndex).Interface(),
RecursiveType: in.RecursiveType,
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
Tags: in.Tags,
Option: in.Option,
},
)
}
@ -451,7 +484,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: rvAttrField.MapIndex(k).Interface(),
RecursiveType: in.RecursiveType,
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
Tags: in.Tags,
Option: in.Option,
},
)
}
@ -490,7 +523,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
Value: reflectValue.Index(i).Interface(),
RecursiveType: in.RecursiveType,
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
Tags: in.Tags,
Option: in.Option,
})
}
return array
@ -500,11 +533,11 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
// MapStrStr converts `value` to map[string]string.
// Note that there might be data copy for this map type converting.
func MapStrStr(value interface{}, tags ...string) map[string]string {
func MapStrStr(value interface{}, option ...MapOption) map[string]string {
if r, ok := value.(map[string]string); ok {
return r
}
m := Map(value, tags...)
m := Map(value, option...)
if len(m) > 0 {
vMap := make(map[string]string, len(m))
for k, v := range m {
@ -517,6 +550,7 @@ func MapStrStr(value interface{}, tags ...string) map[string]string {
// MapStrStrDeep converts `value` to map[string]string recursively.
// Note that there might be data copy for this map type converting.
// Deprecated: used MapStrStr instead.
func MapStrStrDeep(value interface{}, tags ...string) map[string]string {
if r, ok := value.(map[string]string); ok {
return r

View File

@ -9,23 +9,19 @@ package gconv
import "github.com/gogf/gf/v2/internal/json"
// SliceMap is alias of Maps.
func SliceMap(any interface{}) []map[string]interface{} {
return Maps(any)
func SliceMap(any interface{}, option ...MapOption) []map[string]interface{} {
return Maps(any, option...)
}
// SliceMapDeep is alias of MapsDeep.
// Deprecated: used SliceMap instead.
func SliceMapDeep(any interface{}) []map[string]interface{} {
return MapsDeep(any)
}
// SliceStruct is alias of Structs.
func SliceStruct(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
return Structs(params, pointer, mapping...)
}
// Maps converts `value` to []map[string]interface{}.
// Note that it automatically checks and converts json string to []map if `value` is string/[]byte.
func Maps(value interface{}, tags ...string) []map[string]interface{} {
func Maps(value interface{}, option ...MapOption) []map[string]interface{} {
if value == nil {
return nil
}
@ -62,7 +58,7 @@ func Maps(value interface{}, tags ...string) []map[string]interface{} {
}
list := make([]map[string]interface{}, len(array))
for k, v := range array {
list[k] = Map(v, tags...)
list[k] = Map(v, option...)
}
return list
}
@ -71,6 +67,7 @@ func Maps(value interface{}, tags ...string) []map[string]interface{} {
// MapsDeep converts `value` to []map[string]interface{} recursively.
//
// TODO completely implement the recursive converting for all types.
// Deprecated: used Maps instead.
func MapsDeep(value interface{}, tags ...string) []map[string]interface{} {
if value == nil {
return nil

View File

@ -20,6 +20,11 @@ func Structs(params interface{}, pointer interface{}, paramKeyToAttrMap ...map[s
return Scan(params, pointer, paramKeyToAttrMap...)
}
// SliceStruct is alias of Structs.
func SliceStruct(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
return Structs(params, pointer, mapping...)
}
// StructsTag acts as Structs but also with support for priority tag feature, which retrieves the
// specified tags for `params` key-value items to struct attribute names mapping.
// The parameter `priorityTag` supports multiple tags that can be joined with char ','.

View File

@ -946,8 +946,8 @@ func Test_Map_StructWithJsonTag_All(t *testing.T) {
ssa: "222",
}
user2 := &user1
_ = gconv.Map(user1, "Ss")
map1 := gconv.Map(user1, "json", "json2")
_ = gconv.Map(user1, gconv.MapOption{Tags: []string{"Ss"}})
map1 := gconv.Map(user1, gconv.MapOption{Tags: []string{"json", "json2"}})
map2 := gconv.Map(user2)
map3 := gconv.Map(user3)
t.Assert(map1["Uid"], 100)

View File

@ -617,6 +617,53 @@ func TestMapWithJsonOmitEmpty(t *testing.T) {
Key: "",
Value: 1,
}
t.Assert(gconv.Map(s), g.Map{"Value": 1})
m1 := gconv.Map(s)
t.Assert(m1, g.Map{
"Key": "",
"Value": 1,
})
m2 := gconv.Map(s, gconv.MapOption{
Deep: false,
OmitEmpty: true,
Tags: nil,
})
t.Assert(m2, g.Map{
"Value": 1,
})
})
gtest.C(t, func(t *gtest.T) {
type ProductConfig struct {
Pid int `v:"required" json:"pid,omitempty"`
TimeSpan int `v:"required" json:"timeSpan,omitempty"`
}
type CreateGoodsDetail struct {
ProductConfig
AutoRenewFlag int `v:"required" json:"autoRenewFlag"`
}
s := &CreateGoodsDetail{
ProductConfig: ProductConfig{
Pid: 1,
TimeSpan: 0,
},
AutoRenewFlag: 0,
}
m1 := gconv.Map(s)
t.Assert(m1, g.Map{
"pid": 1,
"timeSpan": 0,
"autoRenewFlag": 0,
})
m2 := gconv.Map(s, gconv.MapOption{
Deep: false,
OmitEmpty: true,
Tags: nil,
})
t.Assert(m2, g.Map{
"pid": 1,
"autoRenewFlag": 0,
})
})
}

View File

@ -44,7 +44,7 @@ func newValidationError(code gcode.Code, rules []fieldRule, fieldRuleErrorMap ma
for field, ruleErrorMap := range fieldRuleErrorMap {
for rule, err := range ruleErrorMap {
if !gerror.HasStack(err) {
ruleErrorMap[rule] = gerror.NewOption(gerror.Option{
ruleErrorMap[rule] = gerror.NewWithOption(gerror.Option{
Stack: false,
Text: gstr.Trim(err.Error()),
Code: code,

View File

@ -311,24 +311,28 @@ func Test_Datetime(t *testing.T) {
func Test_DateFormat(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
val1 := "2010"
val2 := "201011"
val3 := "2010.11"
val4 := "201011-01"
val5 := "2010~11~01"
val6 := "2010-11~01"
err1 := g.Validator().Data(val1).Rules("date-format:Y").Run(ctx)
err2 := g.Validator().Data(val2).Rules("date-format:Ym").Run(ctx)
err3 := g.Validator().Data(val3).Rules("date-format:Y.m").Run(ctx)
err4 := g.Validator().Data(val4).Rules("date-format:Ym-d").Run(ctx)
err5 := g.Validator().Data(val5).Rules("date-format:Y~m~d").Run(ctx)
err6 := g.Validator().Data(val6).Rules("date-format:Y~m~d").Run(ctx)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(err3, nil)
t.Assert(err4, nil)
t.Assert(err5, nil)
t.AssertNE(err6, nil)
m := g.MapStrStr{
"2010": "date-format:Y",
"201011": "date-format:Ym",
"2010.11": "date-format:Y.m",
"201011-01": "date-format:Ym-d",
"2010~11~01": "date-format:Y~m~d",
"2010-11~01": "date-format:Y-m~d",
"2023-09-10T19:46:31Z": "date-format:2006-01-02\\T15:04:05Z07:00", // RFC3339
}
for k, v := range m {
err := g.Validator().Data(k).Rules(v).Run(ctx)
t.AssertNil(err)
}
})
gtest.C(t, func(t *gtest.T) {
errM := g.MapStrStr{
"2010-11~01": "date-format:Y~m~d",
}
for k, v := range errM {
err := g.Validator().Data(k).Rules(v).Run(ctx)
t.AssertNE(err, nil)
}
})
gtest.C(t, func(t *gtest.T) {
t1 := gtime.Now()

View File

@ -2,5 +2,5 @@ package gf
const (
// VERSION is the current GoFrame version.
VERSION = "v2.5.7"
VERSION = "v2.6.0-beta"
)