mirror of
https://gitee.com/johng/gf
synced 2026-06-07 18:26:02 +08:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7975e391f0 | |||
| 565790036e | |||
| 44819b135e | |||
| bb19877430 | |||
| fc02e06423 | |||
| dd8a5dcf32 | |||
| 33584506ab | |||
| ee2cf92479 | |||
| 0b6dd6fb13 | |||
| 993467bb3c | |||
| c7c9f0011a | |||
| 9aa872e705 |
2
.github/workflows/golangci-lint.yml
vendored
2
.github/workflows/golangci-lint.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
golangci:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ '1.18','1.19','1.20','1.21' ]
|
||||
go-version: [ '1.18','1.19','1.20','1.21.4' ]
|
||||
name: golangci-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@ -9,6 +9,15 @@
|
||||
[](https://codecov.io/gh/gogf/gf)
|
||||
[](https://github.com/gogf/gf)
|
||||
[](https://github.com/gogf/gf)
|
||||
|
||||
[](https://github.com/gogf/gf/releases)
|
||||
[](https://github.com/gogf/gf/pulls)
|
||||
[](https://github.com/gogf/gf/pulls?q=is%3Apr+is%3Aclosed)
|
||||
[](https://github.com/gogf/gf/issues)
|
||||
[](https://github.com/gogf/gf/issues?q=is%3Aissue+is%3Aclosed)
|
||||

|
||||

|
||||
|
||||
</div>
|
||||
|
||||
`GoFrame` is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -3,14 +3,14 @@ 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/minio/selfupdate v0.6.0
|
||||
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.6.0
|
||||
github.com/gogf/gf/v2 v2.6.0
|
||||
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
golang.org/x/mod v0.9.0
|
||||
golang.org/x/tools v0.7.0
|
||||
|
||||
@ -38,20 +38,8 @@ 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/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f h1:7xfXR/BhG3JDqO1s45n65Oyx9t4E/UqDOXep6jXdLCM=
|
||||
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f/go.mod h1:HnYoio6S7VaFJdryKcD/r9HgX+4QzYfr00XiXUo/xz0=
|
||||
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=
|
||||
@ -87,8 +75,6 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
|
||||
github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
|
||||
github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
@ -140,7 +126,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/minio/selfupdate"
|
||||
"github.com/gogf/selfupdate"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
|
||||
|
||||
@ -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{}
|
||||
)
|
||||
|
||||
@ -59,28 +59,29 @@ CONFIGURATION SUPPORT
|
||||
numeric:
|
||||
type: string
|
||||
`
|
||||
CGenDaoBriefPath = `directory path for generated files`
|
||||
CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
CGenDaoBriefTables = `generate models only for given tables, multiple table names separated with ','`
|
||||
CGenDaoBriefTablesEx = `generate models excluding given tables, multiple table names separated with ','`
|
||||
CGenDaoBriefPrefix = `add prefix for all table of specified link/database tables`
|
||||
CGenDaoBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
|
||||
CGenDaoBriefStdTime = `use time.Time from stdlib instead of gtime.Time for generated time/date fields of tables`
|
||||
CGenDaoBriefWithTime = `add created time for auto produced go files`
|
||||
CGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
|
||||
CGenDaoBriefImportPrefix = `custom import prefix for generated go files`
|
||||
CGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
|
||||
CGenDaoBriefDoPath = `directory path for storing generated do files under path`
|
||||
CGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
|
||||
CGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
|
||||
CGenDaoBriefModelFile = `custom file name for storing generated model content`
|
||||
CGenDaoBriefModelFileForDao = `custom file name generating model for DAO operations like Where/Data. It's empty in default`
|
||||
CGenDaoBriefDescriptionTag = `add comment to description tag for each field`
|
||||
CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
|
||||
CGenDaoBriefNoModelComment = `no model comment will be added for each field`
|
||||
CGenDaoBriefClear = `delete all generated go files that do not exist in database`
|
||||
CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
|
||||
CGenDaoBriefGroup = `
|
||||
CGenDaoBriefPath = `directory path for generated files`
|
||||
CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
CGenDaoBriefTables = `generate models only for given tables, multiple table names separated with ','`
|
||||
CGenDaoBriefTablesEx = `generate models excluding given tables, multiple table names separated with ','`
|
||||
CGenDaoBriefPrefix = `add prefix for all table of specified link/database tables`
|
||||
CGenDaoBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
|
||||
CGenDaoBriefRemoveFieldPrefix = `remove specified prefix of the field, multiple prefix separated with ','`
|
||||
CGenDaoBriefStdTime = `use time.Time from stdlib instead of gtime.Time for generated time/date fields of tables`
|
||||
CGenDaoBriefWithTime = `add created time for auto produced go files`
|
||||
CGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
|
||||
CGenDaoBriefImportPrefix = `custom import prefix for generated go files`
|
||||
CGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
|
||||
CGenDaoBriefDoPath = `directory path for storing generated do files under path`
|
||||
CGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
|
||||
CGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
|
||||
CGenDaoBriefModelFile = `custom file name for storing generated model content`
|
||||
CGenDaoBriefModelFileForDao = `custom file name generating model for DAO operations like Where/Data. It's empty in default`
|
||||
CGenDaoBriefDescriptionTag = `add comment to description tag for each field`
|
||||
CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
|
||||
CGenDaoBriefNoModelComment = `no model comment will be added for each field`
|
||||
CGenDaoBriefClear = `delete all generated go files that do not exist in database`
|
||||
CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
|
||||
CGenDaoBriefGroup = `
|
||||
specifying the configuration group name of database for generated ORM instance,
|
||||
it's not necessary and the default value is "default"
|
||||
`
|
||||
@ -145,6 +146,7 @@ func init() {
|
||||
`CGenDaoBriefTablesEx`: CGenDaoBriefTablesEx,
|
||||
`CGenDaoBriefPrefix`: CGenDaoBriefPrefix,
|
||||
`CGenDaoBriefRemovePrefix`: CGenDaoBriefRemovePrefix,
|
||||
`CGenDaoBriefRemoveFieldPrefix`: CGenDaoBriefRemoveFieldPrefix,
|
||||
`CGenDaoBriefStdTime`: CGenDaoBriefStdTime,
|
||||
`CGenDaoBriefWithTime`: CGenDaoBriefWithTime,
|
||||
`CGenDaoBriefDaoPath`: CGenDaoBriefDaoPath,
|
||||
@ -180,6 +182,7 @@ type (
|
||||
Group string `name:"group" short:"g" brief:"{CGenDaoBriefGroup}" d:"default"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{CGenDaoBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenDaoBriefRemovePrefix}"`
|
||||
RemoveFieldPrefix string `name:"removeFieldPrefix" short:"rf" brief:"{CGenDaoBriefRemoveFieldPrefix}"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
|
||||
ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
|
||||
DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
|
||||
|
||||
@ -138,6 +138,7 @@ type generateDaoInternalInput struct {
|
||||
|
||||
func generateDaoInternal(in generateDaoInternalInput) {
|
||||
path := filepath.FromSlash(gfile.Join(in.DirPathDaoInternal, in.FileName+".go"))
|
||||
removeFieldPrefixArray := gstr.SplitAndTrim(in.RemoveFieldPrefix, ",")
|
||||
modelContent := gstr.ReplaceByMap(
|
||||
getTemplateFromPathOrDefault(in.TplDaoInternalPath, consts.TemplateGenDaoInternalContent),
|
||||
g.MapStrStr{
|
||||
@ -146,8 +147,8 @@ func generateDaoInternal(in generateDaoInternalInput) {
|
||||
tplVarGroupName: in.Group,
|
||||
tplVarTableNameCamelCase: in.TableNameCamelCase,
|
||||
tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
|
||||
tplVarColumnDefine: gstr.Trim(generateColumnDefinitionForDao(in.FieldMap)),
|
||||
tplVarColumnNames: gstr.Trim(generateColumnNamesForDao(in.FieldMap)),
|
||||
tplVarColumnDefine: gstr.Trim(generateColumnDefinitionForDao(in.FieldMap, removeFieldPrefixArray)),
|
||||
tplVarColumnNames: gstr.Trim(generateColumnNamesForDao(in.FieldMap, removeFieldPrefixArray)),
|
||||
})
|
||||
modelContent = replaceDefaultVar(in.CGenDaoInternalInput, modelContent)
|
||||
if err := gfile.PutContents(path, strings.TrimSpace(modelContent)); err != nil {
|
||||
@ -160,16 +161,23 @@ func generateDaoInternal(in generateDaoInternalInput) {
|
||||
|
||||
// generateColumnNamesForDao generates and returns the column names assignment content of column struct
|
||||
// for specified table.
|
||||
func generateColumnNamesForDao(fieldMap map[string]*gdb.TableField) string {
|
||||
func generateColumnNamesForDao(fieldMap map[string]*gdb.TableField, removeFieldPrefixArray []string) string {
|
||||
var (
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
array = make([][]string, len(fieldMap))
|
||||
names = sortFieldKeyForDao(fieldMap)
|
||||
)
|
||||
|
||||
for index, name := range names {
|
||||
field := fieldMap[name]
|
||||
|
||||
newFiledName := field.Name
|
||||
for _, v := range removeFieldPrefixArray {
|
||||
newFiledName = gstr.TrimLeftStr(newFiledName, v, 1)
|
||||
}
|
||||
|
||||
array[index] = []string{
|
||||
" #" + gstr.CaseCamel(field.Name) + ":",
|
||||
" #" + gstr.CaseCamel(newFiledName) + ":",
|
||||
fmt.Sprintf(` #"%s",`, field.Name),
|
||||
}
|
||||
}
|
||||
@ -189,12 +197,13 @@ func generateColumnNamesForDao(fieldMap map[string]*gdb.TableField) string {
|
||||
}
|
||||
|
||||
// generateColumnDefinitionForDao generates and returns the column names definition for specified table.
|
||||
func generateColumnDefinitionForDao(fieldMap map[string]*gdb.TableField) string {
|
||||
func generateColumnDefinitionForDao(fieldMap map[string]*gdb.TableField, removeFieldPrefixArray []string) string {
|
||||
var (
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
array = make([][]string, len(fieldMap))
|
||||
names = sortFieldKeyForDao(fieldMap)
|
||||
)
|
||||
|
||||
for index, name := range names {
|
||||
var (
|
||||
field = fieldMap[name]
|
||||
@ -203,8 +212,12 @@ func generateColumnDefinitionForDao(fieldMap map[string]*gdb.TableField) string
|
||||
"\r", " ",
|
||||
}))
|
||||
)
|
||||
newFiledName := field.Name
|
||||
for _, v := range removeFieldPrefixArray {
|
||||
newFiledName = gstr.TrimLeftStr(newFiledName, v, 1)
|
||||
}
|
||||
array[index] = []string{
|
||||
" #" + gstr.CaseCamel(field.Name),
|
||||
" #" + gstr.CaseCamel(newFiledName),
|
||||
" # " + "string",
|
||||
" #" + fmt.Sprintf(`// %s`, comment),
|
||||
}
|
||||
|
||||
@ -126,8 +126,13 @@ func generateStructFieldDefinition(
|
||||
tagKey = "`"
|
||||
descriptionTag = gstr.Replace(formatComment(field.Comment), `"`, `\"`)
|
||||
)
|
||||
removeFieldPrefixArray := gstr.SplitAndTrim(in.RemoveFieldPrefix, ",")
|
||||
newFiledName := field.Name
|
||||
for _, v := range removeFieldPrefixArray {
|
||||
newFiledName = gstr.TrimLeftStr(newFiledName, v, 1)
|
||||
}
|
||||
attrLines = []string{
|
||||
" #" + gstr.CaseCamel(field.Name),
|
||||
" #" + gstr.CaseCamel(newFiledName),
|
||||
" #" + localTypeNameStr,
|
||||
}
|
||||
attrLines = append(attrLines, " #"+fmt.Sprintf(tagKey+`json:"%s"`, jsonTag))
|
||||
|
||||
@ -31,16 +31,17 @@ import (
|
||||
type (
|
||||
CGenPbEntity struct{}
|
||||
CGenPbEntityInput struct {
|
||||
g.Meta `name:"pbentity" config:"{CGenPbEntityConfig}" brief:"{CGenPbEntityBrief}" eg:"{CGenPbEntityEg}" ad:"{CGenPbEntityAd}"`
|
||||
Path string `name:"path" short:"p" brief:"{CGenPbEntityBriefPath}" d:"manifest/protobuf/pbentity"`
|
||||
Package string `name:"package" short:"k" brief:"{CGenPbEntityBriefPackage}"`
|
||||
Link string `name:"link" short:"l" brief:"{CGenPbEntityBriefLink}"`
|
||||
Tables string `name:"tables" short:"t" brief:"{CGenPbEntityBriefTables}"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{CGenPbEntityBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenPbEntityBriefRemovePrefix}"`
|
||||
NameCase string `name:"nameCase" short:"n" brief:"{CGenPbEntityBriefNameCase}" d:"Camel"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{CGenPbEntityBriefJsonCase}" d:"CamelLower"`
|
||||
Option string `name:"option" short:"o" brief:"{CGenPbEntityBriefOption}"`
|
||||
g.Meta `name:"pbentity" config:"{CGenPbEntityConfig}" brief:"{CGenPbEntityBrief}" eg:"{CGenPbEntityEg}" ad:"{CGenPbEntityAd}"`
|
||||
Path string `name:"path" short:"p" brief:"{CGenPbEntityBriefPath}" d:"manifest/protobuf/pbentity"`
|
||||
Package string `name:"package" short:"k" brief:"{CGenPbEntityBriefPackage}"`
|
||||
Link string `name:"link" short:"l" brief:"{CGenPbEntityBriefLink}"`
|
||||
Tables string `name:"tables" short:"t" brief:"{CGenPbEntityBriefTables}"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{CGenPbEntityBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenPbEntityBriefRemovePrefix}"`
|
||||
RemoveFieldPrefix string `name:"removeFieldPrefix" short:"rf" brief:"{CGenPbEntityBriefRemoveFieldPrefix}"`
|
||||
NameCase string `name:"nameCase" short:"n" brief:"{CGenPbEntityBriefNameCase}" d:"Camel"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{CGenPbEntityBriefJsonCase}" d:"CamelLower"`
|
||||
Option string `name:"option" short:"o" brief:"{CGenPbEntityBriefOption}"`
|
||||
}
|
||||
CGenPbEntityOutput struct{}
|
||||
|
||||
@ -87,14 +88,15 @@ CONFIGURATION SUPPORT
|
||||
option java_package = "protobuf/demos";
|
||||
option php_namespace = "protobuf/demos";
|
||||
`
|
||||
CGenPbEntityBriefPath = `directory path for generated files storing`
|
||||
CGenPbEntityBriefPackage = `package path for all entity proto files`
|
||||
CGenPbEntityBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
CGenPbEntityBriefTables = `generate models only for given tables, multiple table names separated with ','`
|
||||
CGenPbEntityBriefPrefix = `add specified prefix for all entity names and entity proto files`
|
||||
CGenPbEntityBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
|
||||
CGenPbEntityBriefOption = `extra protobuf options`
|
||||
CGenPbEntityBriefGroup = `
|
||||
CGenPbEntityBriefPath = `directory path for generated files storing`
|
||||
CGenPbEntityBriefPackage = `package path for all entity proto files`
|
||||
CGenPbEntityBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
CGenPbEntityBriefTables = `generate models only for given tables, multiple table names separated with ','`
|
||||
CGenPbEntityBriefPrefix = `add specified prefix for all entity names and entity proto files`
|
||||
CGenPbEntityBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
|
||||
CGenPbEntityBriefRemoveFieldPrefix = `remove specified prefix of the field, multiple prefix separated with ','`
|
||||
CGenPbEntityBriefOption = `extra protobuf options`
|
||||
CGenPbEntityBriefGroup = `
|
||||
specifying the configuration group name of database for generated ORM instance,
|
||||
it's not necessary and the default value is "default"
|
||||
`
|
||||
@ -120,20 +122,21 @@ set it to "none" to ignore json tag generating.
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`CGenPbEntityConfig`: CGenPbEntityConfig,
|
||||
`CGenPbEntityBrief`: CGenPbEntityBrief,
|
||||
`CGenPbEntityEg`: CGenPbEntityEg,
|
||||
`CGenPbEntityAd`: CGenPbEntityAd,
|
||||
`CGenPbEntityBriefPath`: CGenPbEntityBriefPath,
|
||||
`CGenPbEntityBriefPackage`: CGenPbEntityBriefPackage,
|
||||
`CGenPbEntityBriefLink`: CGenPbEntityBriefLink,
|
||||
`CGenPbEntityBriefTables`: CGenPbEntityBriefTables,
|
||||
`CGenPbEntityBriefPrefix`: CGenPbEntityBriefPrefix,
|
||||
`CGenPbEntityBriefRemovePrefix`: CGenPbEntityBriefRemovePrefix,
|
||||
`CGenPbEntityBriefGroup`: CGenPbEntityBriefGroup,
|
||||
`CGenPbEntityBriefNameCase`: CGenPbEntityBriefNameCase,
|
||||
`CGenPbEntityBriefJsonCase`: CGenPbEntityBriefJsonCase,
|
||||
`CGenPbEntityBriefOption`: CGenPbEntityBriefOption,
|
||||
`CGenPbEntityConfig`: CGenPbEntityConfig,
|
||||
`CGenPbEntityBrief`: CGenPbEntityBrief,
|
||||
`CGenPbEntityEg`: CGenPbEntityEg,
|
||||
`CGenPbEntityAd`: CGenPbEntityAd,
|
||||
`CGenPbEntityBriefPath`: CGenPbEntityBriefPath,
|
||||
`CGenPbEntityBriefPackage`: CGenPbEntityBriefPackage,
|
||||
`CGenPbEntityBriefLink`: CGenPbEntityBriefLink,
|
||||
`CGenPbEntityBriefTables`: CGenPbEntityBriefTables,
|
||||
`CGenPbEntityBriefPrefix`: CGenPbEntityBriefPrefix,
|
||||
`CGenPbEntityBriefRemovePrefix`: CGenPbEntityBriefRemovePrefix,
|
||||
`CGenPbEntityBriefRemoveFieldPrefix`: CGenPbEntityBriefRemoveFieldPrefix,
|
||||
`CGenPbEntityBriefGroup`: CGenPbEntityBriefGroup,
|
||||
`CGenPbEntityBriefNameCase`: CGenPbEntityBriefNameCase,
|
||||
`CGenPbEntityBriefJsonCase`: CGenPbEntityBriefJsonCase,
|
||||
`CGenPbEntityBriefOption`: CGenPbEntityBriefOption,
|
||||
})
|
||||
}
|
||||
|
||||
@ -351,9 +354,16 @@ func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in CGenPb
|
||||
jsonTagStr = " " + jsonTagStr
|
||||
}
|
||||
}
|
||||
|
||||
removeFieldPrefixArray := gstr.SplitAndTrim(in.RemoveFieldPrefix, ",")
|
||||
newFiledName := field.Name
|
||||
for _, v := range removeFieldPrefixArray {
|
||||
newFiledName = gstr.TrimLeftStr(newFiledName, v, 1)
|
||||
}
|
||||
|
||||
return []string{
|
||||
" #" + localTypeNameStr,
|
||||
" #" + formatCase(field.Name, in.NameCase),
|
||||
" #" + formatCase(newFiledName, in.NameCase),
|
||||
" #= " + gconv.String(index) + jsonTagStr + ";",
|
||||
" #" + fmt.Sprintf(`// %s`, comment),
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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...)
|
||||
}
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -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
|
||||
github.com/hashicorp/consul/api v1.24.0
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||
)
|
||||
|
||||
@ -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
|
||||
k8s.io/api v0.27.4
|
||||
k8s.io/apimachinery v0.27.4
|
||||
k8s.io/client-go v0.27.4
|
||||
|
||||
@ -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
|
||||
github.com/nacos-group/nacos-sdk-go v1.1.4
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
github.com/polarismesh/polaris-go v1.5.5
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/shopspring/decimal v1.3.1
|
||||
)
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -881,3 +881,28 @@ func Test_Issue3086(t *testing.T) {
|
||||
t.Assert(n, 2)
|
||||
})
|
||||
}
|
||||
|
||||
// https://github.com/gogf/gf/issues/3204
|
||||
func Test_Issue3204(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
db.SetDebug(true)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
g.Meta `orm:"do:true"`
|
||||
Id interface{} `orm:"id,omitempty"`
|
||||
Passport interface{} `orm:"passport,omitempty"`
|
||||
Password interface{} `orm:"password,omitempty"`
|
||||
Nickname interface{} `orm:"nickname,omitempty"`
|
||||
CreateTime interface{} `orm:"create_time,omitempty"`
|
||||
}
|
||||
where := User{
|
||||
Id: 2,
|
||||
Passport: "",
|
||||
}
|
||||
all, err := db.Model(table).Where(where).All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(all), 1)
|
||||
t.Assert(all[0]["id"], 2)
|
||||
})
|
||||
}
|
||||
|
||||
@ -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
|
||||
github.com/sijms/go-ora/v2 v2.7.10
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
github.com/lib/pq v1.10.9
|
||||
)
|
||||
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -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
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
github.com/redis/go-redis/v9 v9.2.1
|
||||
go.opentelemetry.io/otel v1.14.0
|
||||
go.opentelemetry.io/otel/trace v1.14.0
|
||||
|
||||
@ -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
|
||||
go.etcd.io/etcd/client/v3 v3.5.7
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.2.0 // indirect
|
||||
|
||||
@ -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
|
||||
github.com/joy999/nacos-sdk-go v0.0.0-20231120071639-10a34b3e7288
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
github.com/polarismesh/polaris-go v1.5.5
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
golang.org/x/sync v0.4.0
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
github.com/gogf/gf/v2 v2.6.0
|
||||
go.opentelemetry.io/otel v1.14.0
|
||||
go.opentelemetry.io/otel/trace v1.14.0
|
||||
google.golang.org/grpc v1.57.2
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.2.0 // indirect
|
||||
|
||||
@ -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
|
||||
go.opentelemetry.io/otel v1.14.0
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.14.0
|
||||
go.opentelemetry.io/otel/sdk v1.14.0
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
@ -60,7 +60,7 @@ func (c *Core) GetFieldType(ctx context.Context, fieldName, table, schema string
|
||||
func (c *Core) ConvertDataForRecord(ctx context.Context, value interface{}, table string) (map[string]interface{}, error) {
|
||||
var (
|
||||
err error
|
||||
data = DataToMapDeep(value)
|
||||
data = MapOrStructToMapDeep(value, false)
|
||||
)
|
||||
for fieldName, fieldValue := range data {
|
||||
data[fieldName], err = c.db.ConvertValueForField(
|
||||
|
||||
@ -210,14 +210,22 @@ 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).
|
||||
// DaToMapDeep is deprecated, use MapOrStructToMapDeep instead.
|
||||
func DaToMapDeep(value interface{}) map[string]interface{} {
|
||||
return MapOrStructToMapDeep(value, false)
|
||||
}
|
||||
|
||||
// MapOrStructToMapDeep 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...)
|
||||
func MapOrStructToMapDeep(value interface{}, omitempty bool) map[string]interface{} {
|
||||
m := gconv.Map(value, gconv.MapOption{
|
||||
Tags: structTagPriority,
|
||||
OmitEmpty: omitempty,
|
||||
})
|
||||
for k, v := range m {
|
||||
switch v.(type) {
|
||||
case time.Time, *time.Time, gtime.Time, *gtime.Time, gjson.Json, *gjson.Json:
|
||||
@ -413,7 +421,7 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n
|
||||
newArgs = formatWhereInterfaces(db, gconv.Interfaces(in.Where), buffer, newArgs)
|
||||
|
||||
case reflect.Map:
|
||||
for key, value := range DataToMapDeep(in.Where) {
|
||||
for key, value := range MapOrStructToMapDeep(in.Where, true) {
|
||||
if in.OmitNil && empty.IsNil(value) {
|
||||
continue
|
||||
}
|
||||
@ -468,7 +476,7 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n
|
||||
var (
|
||||
reflectType = reflectInfo.OriginValue.Type()
|
||||
structField reflect.StructField
|
||||
data = DataToMapDeep(in.Where)
|
||||
data = MapOrStructToMapDeep(in.Where, true)
|
||||
)
|
||||
// If `Prefix` is given, it checks and retrieves the table name.
|
||||
if in.Prefix != "" {
|
||||
|
||||
@ -268,7 +268,7 @@ func (m *Model) doInsertWithOption(ctx context.Context, insertOption InsertOptio
|
||||
|
||||
default:
|
||||
// It uses gconv.Map here to simply fo the type converting from interface{} to map[string]interface{},
|
||||
// as there's another DataToMapDeep in next logic to do the deep converting.
|
||||
// as there's another MapOrStructToMapDeep in next logic to do the deep converting.
|
||||
reflectInfo := reflection.OriginValueAndKind(newData)
|
||||
switch reflectInfo.OriginKind {
|
||||
// If it's slice type, it then converts it to List type.
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
github.com/gogf/gf/contrib/config/consul/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/config/kubecm/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/config/nacos/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/config/polaris/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/registry/etcd/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/registry/file/v2 v2.6.0
|
||||
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
|
||||
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/trace/otlpgrpc/v2 v2.6.0
|
||||
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.6.0
|
||||
github.com/gogf/gf/v2 v2.6.0
|
||||
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
|
||||
|
||||
@ -338,8 +338,8 @@ func (c *Client) callRequest(req *http.Request) (resp *Response, err error) {
|
||||
// raw HTTP request-response procedure.
|
||||
reqBodyContent, _ := io.ReadAll(req.Body)
|
||||
resp.requestBody = reqBodyContent
|
||||
req.Body = utils.NewReadCloser(reqBodyContent, false)
|
||||
for {
|
||||
req.Body = utils.NewReadCloser(reqBodyContent, false)
|
||||
if resp.Response, err = c.Do(req); err != nil {
|
||||
err = gerror.Wrapf(err, `request failed`)
|
||||
// The response might not be nil when err != nil.
|
||||
|
||||
@ -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,
|
||||
})
|
||||
|
||||
@ -117,7 +117,7 @@ func forkReloadProcess(ctx context.Context, newExeFilePath ...string) error {
|
||||
var (
|
||||
path = os.Args[0]
|
||||
)
|
||||
if len(newExeFilePath) > 0 {
|
||||
if len(newExeFilePath) > 0 && newExeFilePath[0] != "" {
|
||||
path = newExeFilePath[0]
|
||||
}
|
||||
var (
|
||||
@ -156,12 +156,12 @@ func forkReloadProcess(ctx context.Context, newExeFilePath ...string) error {
|
||||
}
|
||||
|
||||
// forkRestartProcess creates a new server process.
|
||||
func forkRestartProcess(ctx context.Context, newExeFilePath string) error {
|
||||
func forkRestartProcess(ctx context.Context, newExeFilePath ...string) error {
|
||||
var (
|
||||
path = os.Args[0]
|
||||
)
|
||||
if newExeFilePath != "" {
|
||||
path = newExeFilePath
|
||||
if len(newExeFilePath) > 0 && newExeFilePath[0] != "" {
|
||||
path = newExeFilePath[0]
|
||||
}
|
||||
if err := os.Unsetenv(adminActionReloadEnvKey); err != nil {
|
||||
intlog.Errorf(ctx, `%+v`, err)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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,
|
||||
})
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ','.
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -2,5 +2,5 @@ package gf
|
||||
|
||||
const (
|
||||
// VERSION is the current GoFrame version.
|
||||
VERSION = "v2.5.7"
|
||||
VERSION = "v2.6.0"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user