Compare commits

...

10 Commits

97 changed files with 1006 additions and 149 deletions

View File

@ -34,7 +34,7 @@ jobs:
- name: Build CLI Binary For All Platform
run: |
cd cmd/gf
gf build main.go -n gf -a amd64,386 -s windows,linux,darwin
gf build main.go -n gf -a all -s all
- name: Move Files Before Release
run: |

View File

@ -19,17 +19,6 @@ jobs:
- name: Checkout Github Code
uses: actions/checkout@v3
- name: Update Dependencies
run: make gftidy
- name: Commit & Push Changes
uses: actions-js/push@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
author_name: TagRobot
author_email: tagrobot@goframe.org
message: "auto update version to ${{ github.ref_name }}"
- name: Auto Creating Tags For Contrib Packages
run: |
git config --global user.email "tagrobot@goframe.org"

View File

@ -15,12 +15,21 @@ tidy:
lint:
golangci-lint run
gftidy:
# make version to=v2.4.0
.PHONY: version
version:
$(eval files=$(shell find . -name go.mod))
@set -e; \
# GITHUB_REF_NAME=v2.4.0; \
if [[ $$GITHUB_REF_NAME =~ "v" ]]; then \
latestVersion=$$GITHUB_REF_NAME; \
newVersion=$(to); \
echo "The version will be set to $$newVersion"; \
if [[ $$newVersion =~ "v" ]]; then \
latestVersion=$$newVersion; \
echo "package gf" > version.go; \
echo "" >> version.go; \
echo "const (" >> version.go; \
echo -e "\t// VERSION is the current GoFrame version." >> version.go; \
echo -e "\tVERSION = \"$$latestVersion\"" >> version.go; \
echo ")" >> version.go; \
else \
latestVersion=latest; \
fi; \
@ -37,4 +46,6 @@ gftidy:
go mod tidy; \
cd -; \
fi \
done
done

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.3.3
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.3.3
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.3.3
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.3.3
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.3.3
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.3.3
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.4.0
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.4.0
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.4.0
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.4.0
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.4.0
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.4.0
github.com/gogf/gf/v2 v2.4.0
github.com/olekukonko/tablewriter v0.0.5
golang.org/x/tools v0.7.0
)

View File

@ -124,6 +124,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,14 +1,21 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
"bytes"
"context"
"github.com/olekukonko/tablewriter"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
"github.com/olekukonko/tablewriter"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
)

View File

@ -1,7 +1,14 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
"context"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
@ -12,6 +18,7 @@ var (
type cGen struct {
g.Meta `name:"gen" brief:"{cGenBrief}" dc:"{cGenDc}"`
cGenDao
cGenEnums
cGenPb
cGenPbEntity
cGenService

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -0,0 +1,15 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
"github.com/gogf/gf/cmd/gf/v2/internal/cmd/genenums"
)
type (
cGenEnums = genenums.CGenEnums
)

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import "github.com/gogf/gf/cmd/gf/v2/internal/cmd/genpb"

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import "github.com/gogf/gf/cmd/gf/v2/internal/cmd/genpbentity"

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
@ -33,7 +39,7 @@ like json/xml/yaml/toml/ini.
cTplParseEg = `
gf tpl parse -p ./template -v values.json -r
gf tpl parse -p ./template -v values.json -n *.tpl -r
gf tpl parse -p ./template -v values.json -d '${,}}' -r
gf tpl parse -p ./template -v values.json -d '${{,}}' -r
gf tpl parse -p ./template -v values.json -o ./template.parsed
`
cTplSupportValuesFilePattern = `*.json,*.xml,*.yaml,*.yml,*.toml,*.ini`
@ -63,7 +69,7 @@ func init() {
}
func (c *cTpl) Parse(ctx context.Context, in cTplParseInput) (out *cTplParseOutput, err error) {
if in.Output == "" && in.Replace == false {
if in.Output == "" && !in.Replace {
return nil, gerror.New(`parameter output and replace should not be both empty`)
}
delimiters := gstr.SplitAndTrim(in.Delimiters, ",")

View File

@ -1,11 +1,18 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
"context"
"fmt"
"runtime"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
"github.com/gogf/gf/v2/container/gset"
"runtime"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
"github.com/gogf/gf/v2/frame/g"

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gendao
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gendao
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gendao
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gendao
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gendao
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gendao
import (
@ -5,11 +11,12 @@ import (
"context"
"fmt"
"github.com/olekukonko/tablewriter"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
"github.com/olekukonko/tablewriter"
)
type generateStructDefinitionInput struct {

View File

@ -0,0 +1,83 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genenums
import (
"context"
"golang.org/x/tools/go/packages"
"github.com/gogf/gf/cmd/gf/v2/internal/consts"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
)
type (
CGenEnums struct{}
CGenEnumsInput struct {
g.Meta `name:"enums" config:"{CGenEnumsConfig}" brief:"{CGenEnumsBrief}" eg:"{CGenEnumsEg}"`
Src string `name:"src" short:"s" dc:"source folder path to be parsed" d:"."`
Path string `name:"path" short:"p" dc:"output go file path storing enums content" d:"internal/boot/boot_enums.go"`
Prefix string `name:"prefix" short:"x" dc:"only exports packages that starts with specified prefix"`
}
CGenEnumsOutput struct{}
)
const (
CGenEnumsConfig = `gfcli.gen.enums`
CGenEnumsBrief = `parse go files in current project and generate enums go file`
CGenEnumsEg = `
gf gen enums
gf gen enums -p internal/boot/boot_enums.go
gf gen enums -p internal/boot/boot_enums.go -s .
gf gen enums -x github.com/gogf
`
)
func init() {
gtag.Sets(g.MapStrStr{
`CGenEnumsEg`: CGenEnumsEg,
`CGenEnumsBrief`: CGenEnumsBrief,
`CGenEnumsConfig`: CGenEnumsConfig,
})
}
func (c CGenEnums) Enums(ctx context.Context, in CGenEnumsInput) (out *CGenEnumsOutput, err error) {
realPath := gfile.RealPath(in.Src)
if realPath == "" {
mlog.Fatalf(`source folder path "%s" does not exist`, in.Src)
}
err = gfile.Chdir(realPath)
if err != nil {
mlog.Fatal(err)
}
mlog.Printf(`scanning: %s`, realPath)
cfg := &packages.Config{
Dir: realPath,
Mode: pkgLoadMode,
Tests: false,
}
pkgs, err := packages.Load(cfg)
if err != nil {
mlog.Fatal(err)
}
p := NewEnumsParser(in.Prefix)
p.ParsePackages(pkgs)
var enumsContent = gstr.ReplaceByMap(consts.TemplateGenEnums, g.MapStrStr{
"{PackageName}": gfile.Basename(gfile.Dir(in.Path)),
"{EnumsJson}": "`" + p.Export() + "`",
})
enumsContent = gstr.Trim(enumsContent)
if err = gfile.PutContents(in.Path, enumsContent); err != nil {
return
}
mlog.Printf(`generated: %s`, in.Path)
mlog.Print("done!")
return
}

View File

@ -0,0 +1,140 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genenums
import (
"go/constant"
"go/types"
"golang.org/x/tools/go/packages"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
)
const pkgLoadMode = 0xffffff
type EnumsParser struct {
enums []EnumItem
parsedPkg map[string]struct{}
prefix string
}
type EnumItem struct {
Name string
Value string
Kind constant.Kind // String/Int/Bool/Float/Complex/Unknown
Type string // Pkg.ID + TypeName
}
var standardPackages = make(map[string]struct{})
func init() {
stdPackages, err := packages.Load(nil, "std")
if err != nil {
panic(err)
}
for _, p := range stdPackages {
standardPackages[p.ID] = struct{}{}
}
}
func NewEnumsParser(prefix string) *EnumsParser {
return &EnumsParser{
enums: make([]EnumItem, 0),
parsedPkg: make(map[string]struct{}),
prefix: prefix,
}
}
func (p *EnumsParser) ParsePackages(pkgs []*packages.Package) {
for _, pkg := range pkgs {
p.ParsePackage(pkg)
}
}
func (p *EnumsParser) ParsePackage(pkg *packages.Package) {
// Ignore std packages.
if _, ok := standardPackages[pkg.ID]; ok {
return
}
// Ignore pared packages.
if _, ok := p.parsedPkg[pkg.ID]; ok {
return
}
p.parsedPkg[pkg.ID] = struct{}{}
// Only parse specified prefix.
if p.prefix != "" {
if !gstr.HasPrefix(pkg.ID, p.prefix) {
return
}
}
var (
scope = pkg.Types.Scope()
names = scope.Names()
)
for _, name := range names {
con, ok := scope.Lookup(name).(*types.Const)
if !ok {
// Only constants can be enums.
continue
}
if !con.Exported() {
// Ignore unexported values.
continue
}
var enumType = con.Type().String()
if !gstr.Contains(enumType, "/") {
// Ignore std types.
continue
}
var (
enumName = con.Name()
enumValue = con.Val().ExactString()
enumKind = con.Val().Kind()
)
if con.Val().Kind() == constant.String {
enumValue = constant.StringVal(con.Val())
}
p.enums = append(p.enums, EnumItem{
Name: enumName,
Value: enumValue,
Type: enumType,
Kind: enumKind,
})
}
for _, im := range pkg.Imports {
p.ParsePackage(im)
}
}
func (p *EnumsParser) Export() string {
var typeEnumMap = make(map[string][]interface{})
for _, enum := range p.enums {
if typeEnumMap[enum.Type] == nil {
typeEnumMap[enum.Type] = make([]interface{}, 0)
}
var value interface{}
switch enum.Kind {
case constant.Int:
value = gconv.Int64(enum.Value)
case constant.String:
value = enum.Value
case constant.Float:
value = gconv.Float64(enum.Value)
case constant.Bool:
value = gconv.Bool(enum.Value)
default:
value = enum.Value
}
typeEnumMap[enum.Type] = append(typeEnumMap[enum.Type], value)
}
return gjson.MustEncodeString(typeEnumMap)
}

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genpb
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genpb
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genpb
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genpbentity
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genservice
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genservice
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package genservice
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplateGenDaoIndexContent = `

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplateGenDaoDoContent = `

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplateGenDaoEntityContent = `

View File

@ -0,0 +1,23 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplateGenEnums = `
// ================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// ================================================================================
package {PackageName}
import (
"github.com/gogf/gf/v2/util/gtag"
)
func init() {
gtag.SetGlobalEnums({EnumsJson})
}
`

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplatePbEntityMessageContent = `

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplateGenServiceContentHead = `

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package consts
const TemplateGenServiceLogicContent = `

View File

@ -1 +1,7 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package packed

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package service
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package allyes
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package mlog
import (

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package utils
import (

View File

@ -1,14 +1,21 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package utils
import (
"fmt"
"github.com/gogf/gf/v2/errors/gerror"
"io"
"net/http"
"os"
"strconv"
"time"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
)

View File

@ -1,3 +1,9 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package main
import (

View File

@ -795,11 +795,9 @@ func (a *Array) UnmarshalValue(value interface{}) error {
return nil
}
// Filter `filter func(value interface{}, index int) bool` filter array, value
// means the value of the current element, the index of the current original
// color of value, when the custom function returns True, the element will be
// filtered, otherwise it will not be filtered, `Filter` function returns a new
// array, will not modify the original array.
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *Array) Filter(filter func(index int, value interface{}) bool) *Array {
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -788,11 +788,9 @@ func (a *IntArray) UnmarshalValue(value interface{}) error {
return nil
}
// Filter `filter func(value int, index int) bool` filter array, value
// means the value of the current element, the index of the current original
// color of value, when the custom function returns True, the element will be
// filtered, otherwise it will not be filtered, `Filter` function returns a new
// array, will not modify the original array.
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *IntArray) Filter(filter func(index int, value int) bool) *IntArray {
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -799,11 +799,9 @@ func (a *StrArray) UnmarshalValue(value interface{}) error {
return nil
}
// Filter `filter func(value string, index int) bool` filter array, value
// means the value of the current element, the index of the current original
// color of value, when the custom function returns True, the element will be
// filtered, otherwise it will not be filtered, `Filter` function returns a new
// array, will not modify the original array.
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *StrArray) Filter(filter func(index int, value string) bool) *StrArray {
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -761,11 +761,9 @@ func (a *SortedArray) FilterNil() *SortedArray {
return a
}
// Filter `filter func(value interface{}, index int) bool` filter array, value
// means the value of the current element, the index of the current original
// color of value, when the custom function returns True, the element will be
// filtered, otherwise it will not be filtered, `Filter` function returns a new
// array, will not modify the original array.
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *SortedArray) Filter(filter func(index int, value interface{}) bool) *SortedArray {
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -709,11 +709,9 @@ func (a *SortedIntArray) UnmarshalValue(value interface{}) (err error) {
return err
}
// Filter `filter func(value int, index int) bool` filter array, value
// means the value of the current element, the index of the current original
// color of value, when the custom function returns True, the element will be
// filtered, otherwise it will not be filtered, `Filter` function returns a new
// array, will not modify the original array.
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *SortedIntArray) Filter(filter func(index int, value int) bool) *SortedIntArray {
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -722,11 +722,9 @@ func (a *SortedStrArray) UnmarshalValue(value interface{}) (err error) {
return err
}
// Filter `filter func(value string, index int) bool` filter array, value
// means the value of the current element, the index of the current original
// color of value, when the custom function returns True, the element will be
// filtered, otherwise it will not be filtered, `Filter` function returns a new
// array, will not modify the original array.
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *SortedStrArray) Filter(filter func(index int, value string) bool) *SortedStrArray {
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/apolloconfig/agollo/v4 v4.1.1
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
)
replace github.com/gogf/gf/v2 => ../../../

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/kubecm/v2
go 1.18
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
k8s.io/api v0.25.2
k8s.io/apimachinery v0.25.2
k8s.io/client-go v0.25.2

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/nacos/v2
go 1.15
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
github.com/nacos-group/nacos-sdk-go v1.1.2
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/polaris/v2
go 1.15
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
github.com/polarismesh/polaris-go v1.3.0
)

View File

@ -0,0 +1,43 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package clickhouse
import (
"github.com/shopspring/decimal"
"testing"
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gconv"
)
func Test_Issue2584(t *testing.T) {
type TDecimal struct {
F1 *decimal.Decimal `json:"f1"`
}
gtest.C(t, func(t *gtest.T) {
var (
p1 = TDecimal{}
data1 = g.Map{"f1": gvar.New(1111.111)}
err = gconv.Scan(data1, &p1)
)
t.AssertNil(err)
t.Assert(p1.F1, 1111.111)
})
gtest.C(t, func(t *gtest.T) {
var (
p2 = TDecimal{}
data2 = g.Map{"f1": gvar.New("2222.222")}
err = gconv.Scan(data2, &p2)
)
t.AssertNil(err)
t.Assert(p2.F1, 2222.222)
})
}

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/ClickHouse/clickhouse-go/v2 v2.0.15
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
github.com/google/uuid v1.3.0
github.com/shopspring/decimal v1.3.1
)

View File

@ -6,5 +6,5 @@ replace github.com/gogf/gf/v2 => ../../../
require (
gitee.com/chunanyong/dm v1.8.10
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
)

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/denisenkom/go-mssqldb v0.11.0
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
)
replace github.com/gogf/gf/v2 => ../../../

View File

@ -286,7 +286,6 @@ func Test_DB_Insert(t *testing.T) {
t.Assert(one["PASSPORT"].String(), "t200")
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d71qw07ad")
t.Assert(one["NICKNAME"].String(), "T200")
t.Assert(one["CREATE_TIME"].GTime(), timeNow)
})
}

View File

@ -25,7 +25,7 @@ import (
func TestPage(t *testing.T) {
table := createInitTable()
defer dropTable(table)
db.SetDebug(true)
//db.SetDebug(true)
result, err := db.Model(table).Page(1, 2).Order("id").All()
gtest.Assert(err, nil)
fmt.Println("page:1--------", result)

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/go-sql-driver/mysql v1.6.0
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
)
replace github.com/gogf/gf/v2 => ../../../

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/drivers/oracle/v2
go 1.17
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
github.com/sijms/go-ora/v2 v2.4.20
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/drivers/pgsql/v2
go 1.15
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
github.com/lib/pq v1.10.4
)

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/glebarez/go-sqlite v1.17.3
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
)
replace github.com/gogf/gf/v2 => ../../../

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/go-redis/redis/v8 v8.11.5
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
go.opentelemetry.io/otel v1.7.0
go.opentelemetry.io/otel/trace v1.7.0
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/etcd/v2
go 1.15
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
go.etcd.io/etcd/client/v3 v3.5.4
)

View File

@ -0,0 +1,50 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package file_test
import (
"fmt"
"testing"
"time"
"github.com/gogf/gf/contrib/registry/file/v2"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/net/gsvc"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/guid"
)
var ctx = gctx.GetInitCtx()
func Test_HTTP_Registry(t *testing.T) {
var (
svcName = guid.S()
dirPath = gfile.Temp(svcName)
)
defer gfile.Remove(dirPath)
gsvc.SetRegistry(file.New(dirPath))
s := g.Server(svcName)
s.BindHandler("/http-registry", func(r *ghttp.Request) {
r.Response.Write(svcName)
})
s.SetDumpRouterMap(false)
s.Start()
defer s.Shutdown()
time.Sleep(100 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
client := g.Client()
client.SetPrefix(fmt.Sprintf("http://%s", svcName))
// GET
t.Assert(client.GetContent(ctx, "/http-registry"), svcName)
})
}

View File

@ -2,6 +2,6 @@ module github.com/gogf/gf/contrib/registry/file/v2
go 1.15
require github.com/gogf/gf/v2 v2.3.3
require github.com/gogf/gf/v2 v2.4.0
replace github.com/gogf/gf/v2 => ../../../

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/polaris/v2
go 1.15
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
github.com/polarismesh/polaris-go v1.3.0
)

View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/go-zookeeper/zk v1.0.3
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
golang.org/x/sync v0.1.0
)

View File

@ -3,8 +3,8 @@ module github.com/gogf/gf/contrib/rpc/grpcx/v2
go 1.15
require (
github.com/gogf/gf/contrib/registry/file/v2 v2.3.3
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/contrib/registry/file/v2 v2.4.0
github.com/gogf/gf/v2 v2.4.0
go.opentelemetry.io/otel v1.10.0
go.opentelemetry.io/otel/trace v1.10.0
golang.org/x/net v0.0.0-20220919232410-f2f64ebce3c1 // indirect

View File

@ -7,6 +7,7 @@
package grpcx
import (
"context"
"fmt"
"net"
"os"
@ -25,6 +26,7 @@ import (
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
)
// GrpcServer is the server for GRPC protocol.
@ -104,19 +106,19 @@ func (s *GrpcServer) Run() {
// Create listener to bind listening ip and port.
s.listener, err = net.Listen("tcp", s.config.Address)
if err != nil {
s.config.Logger.Fatalf(ctx, `%+v`, err)
s.Logger().Fatalf(ctx, `%+v`, err)
}
// Start listening.
go func() {
if err = s.Server.Serve(s.listener); err != nil {
s.config.Logger.Fatalf(ctx, `%+v`, err)
s.Logger().Fatalf(ctx, `%+v`, err)
}
}()
// Service register.
s.doServiceRegister()
s.config.Logger.Infof(
s.Logger().Infof(
ctx,
"pid[%d]: grpc server started listening on [%s]",
gproc.Pid(), s.GetListenedAddress(),
@ -147,7 +149,7 @@ func (s *GrpcServer) doSignalListen() {
syscall.SIGKILL,
syscall.SIGTERM,
syscall.SIGABRT:
s.config.Logger.Infof(ctx, "signal received: %s, gracefully shutting down", sig.String())
s.Logger().Infof(ctx, "signal received: %s, gracefully shutting down", sig.String())
s.doServiceDeregister()
time.Sleep(time.Second)
s.Stop()
@ -156,6 +158,11 @@ func (s *GrpcServer) doSignalListen() {
}
}
// Logger is alias of GetLogger.
func (s *GrpcServer) Logger() *glog.Logger {
return s.config.Logger
}
// doServiceRegister registers current service to Registry.
func (s *GrpcServer) doServiceRegister() {
if s.registrar == nil {
@ -176,15 +183,19 @@ func (s *GrpcServer) doServiceRegister() {
for i, service := range s.services {
service = &gsvc.LocalService{
Name: service.GetName(),
Endpoints: s.calculateListenedEndpoints(),
Endpoints: s.calculateListenedEndpoints(ctx),
Metadata: service.GetMetadata(),
}
service.GetMetadata().Sets(gsvc.Metadata{
gsvc.MDProtocol: protocol,
})
s.config.Logger.Debugf(ctx, `service register: %+v`, service)
s.Logger().Debugf(ctx, `service register: %+v`, service)
if len(service.GetEndpoints()) == 0 {
s.Logger().Warningf(ctx, `no endpoints found to register service, abort service registering`)
return
}
if service, err = s.registrar.Register(ctx, service); err != nil {
s.config.Logger.Fatalf(ctx, `%+v`, err)
s.Logger().Fatalf(ctx, `%+v`, err)
}
s.services[i] = service
}
@ -197,9 +208,9 @@ func (s *GrpcServer) doServiceDeregister() {
}
var ctx = gctx.GetInitCtx()
for _, service := range s.services {
s.config.Logger.Debugf(ctx, `service deregister: %+v`, service)
s.Logger().Debugf(ctx, `service deregister: %+v`, service)
if err := s.registrar.Deregister(ctx, service); err != nil {
s.config.Logger.Errorf(ctx, `%+v`, err)
s.Logger().Errorf(ctx, `%+v`, err)
}
}
}
@ -249,22 +260,59 @@ func (s *GrpcServer) GetListenedPort() int {
return -1
}
func (s *GrpcServer) calculateListenedEndpoints() gsvc.Endpoints {
func (s *GrpcServer) calculateListenedEndpoints(ctx context.Context) gsvc.Endpoints {
var (
address = s.config.Address
endpoints = make(gsvc.Endpoints, 0)
listenedPort = s.GetListenedPort()
listenedIps []string
configAddr = s.config.Address
endpoints = make(gsvc.Endpoints, 0)
)
var addrArray = gstr.Split(address, ":")
switch addrArray[0] {
case "0.0.0.0", "":
listenedIps = []string{gipv4.MustGetIntranetIp()}
default:
listenedIps = []string{addrArray[0]}
}
for _, ip := range listenedIps {
endpoints = append(endpoints, gsvc.NewEndpoint(fmt.Sprintf(`%s:%d`, ip, listenedPort)))
for _, address := range gstr.SplitAndTrim(configAddr, ",") {
var (
addrArray = gstr.Split(address, ":")
listenedIps []string
listenedPorts []int
)
// IPs.
switch addrArray[0] {
case "127.0.0.1":
// Nothing to do.
case "0.0.0.0", "":
intranetIps, err := gipv4.GetIntranetIpArray()
if err != nil {
s.Logger().Errorf(ctx, `error retrieving intranet ip: %+v`, err)
return nil
}
// If no intranet ips found, it uses all ips that can be retrieved,
// it may include internet ip.
if len(intranetIps) == 0 {
allIps, err := gipv4.GetIpArray()
if err != nil {
s.Logger().Errorf(ctx, `error retrieving ip from current node: %+v`, err)
return nil
}
s.Logger().Noticef(
ctx,
`no intranet ip found, using internet ip to register service: %v`,
allIps,
)
listenedIps = allIps
break
}
listenedIps = intranetIps
default:
listenedIps = []string{addrArray[0]}
}
// Ports.
switch addrArray[1] {
case "0":
listenedPorts = []int{s.GetListenedPort()}
default:
listenedPorts = []int{gconv.Int(addrArray[1])}
}
for _, ip := range listenedIps {
for _, port := range listenedPorts {
endpoints = append(endpoints, gsvc.NewEndpoint(fmt.Sprintf(`%s:%d`, ip, port)))
}
}
}
return endpoints
}

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/trace/jaeger/v2
go 1.15
require (
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/v2 v2.4.0
go.opentelemetry.io/otel v1.7.0
go.opentelemetry.io/otel/exporters/jaeger v1.7.0
go.opentelemetry.io/otel/sdk v1.7.0

View File

@ -3,18 +3,18 @@ module github.com/gogf/gf/example
go 1.15
require (
github.com/gogf/gf/contrib/config/apollo/v2 v2.3.3
github.com/gogf/gf/contrib/config/kubecm/v2 v2.3.3
github.com/gogf/gf/contrib/config/nacos/v2 v2.3.3
github.com/gogf/gf/contrib/config/polaris/v2 v2.3.3
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.3.3
github.com/gogf/gf/contrib/nosql/redis/v2 v2.3.3
github.com/gogf/gf/contrib/registry/etcd/v2 v2.3.3
github.com/gogf/gf/contrib/registry/file/v2 v2.3.3
github.com/gogf/gf/contrib/registry/polaris/v2 v2.3.3
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.3.3
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.3.3
github.com/gogf/gf/v2 v2.3.3
github.com/gogf/gf/contrib/config/apollo/v2 v2.4.0
github.com/gogf/gf/contrib/config/kubecm/v2 v2.4.0
github.com/gogf/gf/contrib/config/nacos/v2 v2.4.0
github.com/gogf/gf/contrib/config/polaris/v2 v2.4.0
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.4.0
github.com/gogf/gf/contrib/nosql/redis/v2 v2.4.0
github.com/gogf/gf/contrib/registry/etcd/v2 v2.4.0
github.com/gogf/gf/contrib/registry/file/v2 v2.4.0
github.com/gogf/gf/contrib/registry/polaris/v2 v2.4.0
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.4.0
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.0
github.com/gogf/gf/v2 v2.4.0
github.com/nacos-group/nacos-sdk-go v1.1.2
github.com/polarismesh/polaris-go v1.3.0
google.golang.org/grpc v1.49.0

View File

@ -518,9 +518,9 @@ func (s *Server) startServer(fdMap listenerFdMap) {
}
var array []string
if v, ok := fdMap["http"]; ok && len(v) > 0 {
array = strings.Split(v, ",")
array = gstr.SplitAndTrim(v, ",")
} else {
array = strings.Split(s.config.Address, ",")
array = gstr.SplitAndTrim(s.config.Address, ",")
}
for _, v := range array {
if len(v) == 0 {
@ -555,7 +555,9 @@ func (s *Server) startServer(fdMap listenerFdMap) {
var err error
// Create listener.
if server.isHttps {
err = server.CreateListenerTLS(s.config.HTTPSCertPath, s.config.HTTPSKeyPath, s.config.TLSConfig)
err = server.CreateListenerTLS(
s.config.HTTPSCertPath, s.config.HTTPSKeyPath, s.config.TLSConfig,
)
} else {
err = server.CreateListener()
}

View File

@ -186,6 +186,7 @@ func (s *gracefulServer) GetListenedAddress() string {
}
// GetListenedPort retrieves and returns one port which is listened to by current server.
// Note that this method is only available if the server is listening on one port.
func (s *gracefulServer) GetListenedPort() int {
if ln := s.getRawListener(); ln != nil {
return ln.Addr().(*net.TCPAddr).Port

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"fmt"
"github.com/gogf/gf/v2/net/gipv4"
@ -37,10 +38,14 @@ func (s *Server) doServiceRegister() {
}
s.service = &gsvc.LocalService{
Name: s.GetName(),
Endpoints: s.calculateListenedEndpoints(),
Endpoints: s.calculateListenedEndpoints(ctx),
Metadata: metadata,
}
s.Logger().Debugf(ctx, `service register: %+v`, s.service)
if len(s.service.GetEndpoints()) == 0 {
s.Logger().Warningf(ctx, `no endpoints found to register service, abort service registering`)
return
}
if s.service, err = s.registrar.Register(ctx, s.service); err != nil {
s.Logger().Fatalf(ctx, `%+v`, err)
}
@ -58,32 +63,61 @@ func (s *Server) doServiceDeregister() {
}
}
func (s *Server) calculateListenedEndpoints() gsvc.Endpoints {
func (s *Server) calculateListenedEndpoints(ctx context.Context) gsvc.Endpoints {
var (
address = s.config.Address
endpoints = make(gsvc.Endpoints, 0)
listenedIps []string
listenedPorts []int
configAddr = s.config.Address
endpoints = make(gsvc.Endpoints, 0)
)
if address == "" {
address = s.config.HTTPSAddr
if configAddr == "" {
configAddr = s.config.HTTPSAddr
}
var addrArray = gstr.Split(address, ":")
switch addrArray[0] {
case "0.0.0.0", "":
listenedIps = []string{gipv4.MustGetIntranetIp()}
default:
listenedIps = []string{addrArray[0]}
}
switch addrArray[1] {
case "0":
listenedPorts = s.GetListenedPorts()
default:
listenedPorts = []int{gconv.Int(addrArray[1])}
}
for _, ip := range listenedIps {
for _, port := range listenedPorts {
endpoints = append(endpoints, gsvc.NewEndpoint(fmt.Sprintf(`%s:%d`, ip, port)))
for _, address := range gstr.SplitAndTrim(configAddr, ",") {
var (
addrArray = gstr.Split(address, ":")
listenedIps []string
listenedPorts []int
)
// IPs.
switch addrArray[0] {
case "127.0.0.1":
// Nothing to do.
case "0.0.0.0", "":
intranetIps, err := gipv4.GetIntranetIpArray()
if err != nil {
s.Logger().Errorf(ctx, `error retrieving intranet ip: %+v`, err)
return nil
}
// If no intranet ips found, it uses all ips that can be retrieved,
// it may include internet ip.
if len(intranetIps) == 0 {
allIps, err := gipv4.GetIpArray()
if err != nil {
s.Logger().Errorf(ctx, `error retrieving ip from current node: %+v`, err)
return nil
}
s.Logger().Noticef(
ctx,
`no intranet ip found, using internet ip to register service: %v`,
allIps,
)
listenedIps = allIps
break
}
listenedIps = intranetIps
default:
listenedIps = []string{addrArray[0]}
}
// Ports.
switch addrArray[1] {
case "0":
listenedPorts = s.GetListenedPorts()
default:
listenedPorts = []int{gconv.Int(addrArray[1])}
}
for _, ip := range listenedIps {
for _, port := range listenedPorts {
endpoints = append(endpoints, gsvc.NewEndpoint(fmt.Sprintf(`%s:%d`, ip, port)))
}
}
}
return endpoints

View File

@ -7,11 +7,13 @@
package goai
import (
"fmt"
"reflect"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/gtag"
)
type SchemaRefs []SchemaRef
@ -41,6 +43,8 @@ func (oai *OpenApiV3) newSchemaRefWithGolangType(golangType reflect.Type, tagMap
err error
oaiType = oai.golangTypeToOAIType(golangType)
oaiFormat = oai.golangTypeToOAIFormat(golangType)
typeName = golangType.Name()
pkgPath = golangType.PkgPath()
schemaRef = &SchemaRef{}
schema = &Schema{
Type: oaiType,
@ -48,6 +52,23 @@ func (oai *OpenApiV3) newSchemaRefWithGolangType(golangType reflect.Type, tagMap
XExtensions: make(XExtensions),
}
)
if pkgPath == "" {
switch golangType.Kind() {
case reflect.Ptr, reflect.Array, reflect.Slice:
pkgPath = golangType.Elem().PkgPath()
typeName = golangType.Elem().Name()
}
}
// Type enums.
var typeId = fmt.Sprintf(`%s.%s`, pkgPath, typeName)
if enums := gtag.GetEnumsByType(typeId); enums != "" {
schema.Enum = make([]interface{}, 0)
if err = json.Unmarshal([]byte(enums), &schema.Enum); err != nil {
return nil, err
}
}
if len(tagMap) > 0 {
if err := oai.tagMapToSchema(tagMap, schema); err != nil {
return nil, err

View File

@ -12,11 +12,13 @@ import (
"net/http"
"testing"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/net/goai"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gmeta"
"github.com/gogf/gf/v2/util/gtag"
)
func Test_Basic(t *testing.T) {
@ -1123,3 +1125,42 @@ func Test_EmptyJsonNameWithOmitEmpty(t *testing.T) {
t.Assert(oai.Components.Schemas.Get(reqKey).Value.Properties.Get("None"), nil)
})
}
func Test_Enums(t *testing.T) {
type Status string
const (
StatusA Status = "a"
StatusB Status = "b"
)
type Req struct {
gmeta.Meta `path:"/CreateResourceReq" method:"POST" tags:"default"`
Name string `dc:"实例名称" json:",omitempty"`
Status1 Status `dc:"状态1" json:",omitempty"`
Status2 *Status `dc:"状态2" json:",omitempty"`
Status3 []Status `dc:"状态2" json:",omitempty"`
Status4 []*Status `dc:"状态2" json:",omitempty"`
}
gtest.C(t, func(t *gtest.T) {
var (
err error
oai = goai.New()
req = new(Req)
)
err = gtag.SetGlobalEnums(gjson.MustEncodeString(g.Map{
"github.com/gogf/gf/v2/net/goai_test.Status": []interface{}{StatusA, StatusB},
}))
t.AssertNil(err)
err = oai.Add(goai.AddInput{
Object: req,
})
t.AssertNil(err)
var reqKey = "github.com.gogf.gf.v2.net.goai_test.Req"
t.AssertNE(oai.Components.Schemas.Get(reqKey).Value.Properties.Get("Name"), nil)
t.Assert(oai.Components.Schemas.Get(reqKey).Value.Properties.Get("Status1").Value.Enum, g.Slice{"a", "b"})
t.Assert(oai.Components.Schemas.Get(reqKey).Value.Properties.Get("Status2").Value.Enum, g.Slice{"a", "b"})
t.Assert(oai.Components.Schemas.Get(reqKey).Value.Properties.Get("Status3").Value.Items.Value.Enum, g.Slice{"a", "b"})
t.Assert(oai.Components.Schemas.Get(reqKey).Value.Properties.Get("Status4").Value.Items.Value.Enum, g.Slice{"a", "b"})
})
}

View File

@ -103,9 +103,7 @@ func (c *Command) doAddCommand(command *Command) error {
// AddObject adds one or more sub-commands to current command using struct object.
func (c *Command) AddObject(objects ...interface{}) error {
var (
commands []*Command
)
var commands []*Command
for _, object := range objects {
rootCommand, err := NewFromObject(object)
if err != nil {

View File

@ -35,6 +35,13 @@ var (
// NewFromObject creates and returns a root command object using given object.
func NewFromObject(object interface{}) (rootCmd *Command, err error) {
switch c := object.(type) {
case Command:
return &c, nil
case *Command:
return c, nil
}
originValueAndKind := reflection.OriginValueAndKind(object)
if originValueAndKind.OriginKind != reflect.Struct {
err = gerror.Newf(

View File

@ -133,6 +133,11 @@ gf get golang.org/x/sys
}
err = commandRoot.AddCommand(
commandEnv,
)
if err != nil {
g.Log().Fatal(ctx, err)
}
err = commandRoot.AddObject(
commandTest,
)
if err != nil {

View File

@ -254,22 +254,50 @@ func doConvert(in doConvertInput) (convertedValue interface{}) {
default:
if in.ReferValue != nil {
var referReflectValue reflect.Value
var (
referReflectValue reflect.Value
)
if v, ok := in.ReferValue.(reflect.Value); ok {
referReflectValue = v
} else {
referReflectValue = reflect.ValueOf(in.ReferValue)
}
defer func() {
if recover() != nil {
in.alreadySetToReferValue = false
if err := bindVarToReflectValue(referReflectValue, in.FromValue, nil); err == nil {
in.alreadySetToReferValue = true
convertedValue = referReflectValue.Interface()
}
}
}()
if referReflectValue.Kind() == reflect.Ptr {
// Type converting for custom type pointers.
// Eg:
// type PayMode int
// type Req struct{
// Mode *PayMode
// }
//
// Struct(`{"Mode": 1000}`, &req)
originType := referReflectValue.Type().Elem()
switch originType.Kind() {
case reflect.Struct:
// Not support some kinds.
default:
in.ToTypeName = originType.Kind().String()
in.ReferValue = nil
refElementValue := reflect.ValueOf(doConvert(in))
originTypeValue := reflect.New(refElementValue.Type()).Elem()
originTypeValue.Set(refElementValue)
in.alreadySetToReferValue = true
return originTypeValue.Addr().Convert(referReflectValue.Type()).Interface()
}
}
in.ToTypeName = referReflectValue.Kind().String()
in.ReferValue = nil
in.alreadySetToReferValue = true
return reflect.ValueOf(doConvert(in)).Convert(referReflectValue.Type()).Interface()
}
return in.FromValue

View File

@ -422,6 +422,8 @@ func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value i
valueBytes = b
} else if s, ok := value.(string); ok {
valueBytes = []byte(s)
} else if f, ok := value.(iString); ok {
valueBytes = []byte(f.String())
}
if len(valueBytes) > 0 {
return v.UnmarshalText(valueBytes), ok
@ -434,6 +436,8 @@ func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value i
valueBytes = b
} else if s, ok := value.(string); ok {
valueBytes = []byte(s)
} else if f, ok := value.(iString); ok {
valueBytes = []byte(f.String())
}
if len(valueBytes) > 0 {

View File

@ -1321,3 +1321,31 @@ func Test_Scan_WithDoubleSliceAttribute(t *testing.T) {
})
}
func Test_Struct_WithCustomType(t *testing.T) {
type PayMode int
type Req1 struct {
PayMode PayMode
}
type Req2 struct {
PayMode *PayMode
}
var (
params = gconv.Map(`{"PayMode": 1000}`)
req1 *Req1
req2 *Req2
err1 error
err2 error
)
err1 = gconv.Struct(params, &req1)
err2 = gconv.Struct(params, &req2)
gtest.C(t, func(t *gtest.T) {
t.AssertNil(err1)
t.Assert(req1.PayMode, 1000)
t.AssertNil(err2)
t.AssertNE(req2.PayMode, nil)
t.Assert(*req2.PayMode, 1000)
})
}

28
util/gtag/gtag_enums.go Normal file
View File

@ -0,0 +1,28 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gtag
import (
"github.com/gogf/gf/v2/internal/json"
)
var (
// Type name => enums json.
enumsMap = make(map[string]json.RawMessage)
)
// SetGlobalEnums sets the global enums into package.
// Note that this operation is not concurrent safety.
func SetGlobalEnums(enumsJson string) error {
return json.Unmarshal([]byte(enumsJson), &enumsMap)
}
// GetEnumsByType retrieves and returns the stored enums json by type name.
// The type name is like: github.com/gogf/gf/v2/encoding/gjson.ContentType
func GetEnumsByType(typeName string) string {
return string(enumsMap[typeName])
}

View File

@ -1,6 +1,6 @@
package gf
const (
// VERSION is the current GoFrame version.
VERSION = "v2.4.0-rc"
// VERSION is the current GoFrame version.
VERSION = "v2.4.0"
)