Compare commits

...

22 Commits

Author SHA1 Message Date
ec6c537def feat(cmd/gf): project template updates for command gf init (#3928) 2024-11-17 10:57:17 +08:00
bcfcda793c chore(errors/gerror): add examples (#3927) 2024-11-16 18:14:40 +08:00
138dea0f3a feat(cmd/gf): change document source from repo gf to gf-site (#3926) 2024-11-15 14:33:23 +08:00
3d4904eb3d feat(net/ghttp): remove Req/Res suffix limitation for input/output parameters of strict router handler (#3848) 2024-11-14 17:58:39 +08:00
955a76cf35 feat: new version v2.8.0 (#3924) 2024-11-14 13:26:23 +08:00
ffa6081471 fix(util/gconv): fix missing minus in string to int64 conversion (#3920) 2024-11-13 23:25:24 +08:00
6baf4338b0 fix(database/gdb): recognize field type tinyint(1) to golang type bool (#3921) 2024-11-13 23:09:01 +08:00
8c6db247b2 chore: readme updates (#3919) 2024-11-13 20:48:02 +08:00
fff2f8a24c build: downgrade fsnotify from v1.8.0 to v1.7.0 to solve data race error (#3916) 2024-11-13 12:22:23 +08:00
475e8bbae0 chore: README.md updates (#3912) 2024-11-12 21:30:46 +08:00
070efecc6e style(gtest/test): improve code (#3891) 2024-11-12 20:20:13 +08:00
a63af5d5f8 build: upgrade fsnotify from v1.7.0 to v1.8.0 to solve occasional ci failure (#3910) 2024-11-12 10:25:39 +08:00
bd2e8408e8 chore: update README.MD (#3911) 2024-11-12 09:25:37 +08:00
6c6fd7902a feat(database/gdb): remove unnecessary blank character requirement in tag for With feature of gdb.Model (#3875) 2024-11-11 21:59:26 +08:00
1b7b536d6c fix(cmd/gf): protoc file comments contain backticks and double quotes, resulting in syntax errors in the generated file of go (#3890) 2024-11-11 21:37:30 +08:00
9cc1cf1b53 fix(cmd/gf): remove dir after process done if given build file parameter is not a file but a dir name (#3908) 2024-11-11 21:32:58 +08:00
76948d93d6 test(drivers/mysql): use asserts function to replace if statement (#3849) 2024-11-11 20:54:57 +08:00
5ba165a3c0 fix(cmd/gf): go back current working directory after gf gen pb (#3895) 2024-11-11 20:42:25 +08:00
f4db846633 fix(contrib/drivers/pgsql): connection fails when postgres database password is empty (#3900) 2024-11-11 20:27:07 +08:00
e7cc2c3d9c chore: update the contributors in README.MD (#3907) 2024-11-06 22:11:23 +08:00
01cd0103e4 fix(net/gclient): Client Clone with allocated header/cookie (#3902) 2024-11-06 22:09:28 +08:00
d1872f17f7 fix(util/gconv): assigned the same value to struct field and its same name field in embedded struct failed (#3905) 2024-11-06 21:12:01 +08:00
77 changed files with 828 additions and 894 deletions

View File

@ -220,7 +220,19 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache-dependency-path: '**/go.sum'
cache-dependency-path: '**/go.sum'
- name: Install Protoc
uses: arduino/setup-protoc@v2
with:
version: "23.x"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the protocol compiler plugins for Go
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
export PATH="$PATH:$(go env GOPATH)/bin"
- name: Before Script
run: bash .github/workflows/before_script.sh

View File

@ -1,7 +1,7 @@
# GoFrame
<div align=center>
<img src="https://goframe.org/statics/image/logo2.png?v=1" width="300"/>
<img src="https://goframe.org/img/logo_full.png" width="300"/>
[![Go Reference](https://pkg.go.dev/badge/github.com/gogf/gf/v2.svg)](https://pkg.go.dev/github.com/gogf/gf/v2)
[![GoFrame CI](https://github.com/gogf/gf/actions/workflows/ci-main.yml/badge.svg)](https://github.com/gogf/gf/actions/workflows/ci-main.yml)
@ -37,6 +37,12 @@
- OpenAPIV3 documentation generating, automatically
- much, much more...ready to explore?
# Documentation
- GoFrame Official Site: [https://goframe.org](https://goframe.org)
- GoDoc API: [https://pkg.go.dev/github.com/gogf/gf/v2](https://pkg.go.dev/github.com/gogf/gf/v2)
# Installation
Enter your repo. directory and execute following command:
@ -59,41 +65,22 @@ go install github.com/gogf/gf/cmd/gf/v2@latest
golang version >= 1.20
```
# Documentation
# Contributors
- Chinese Official Site(中文官网): [https://goframe.org](https://goframe.org/display/gf)
- Chinese Pages Document(中文镜像文档): [https://pages.goframe.org](https://pages.goframe.org)
- Chinese Offline Document(中文离线文档): [https://github.com/gogf/goframe.org-pdf](https://github.com/gogf/goframe.org-pdf)
- GoDoc API: [https://pkg.go.dev/github.com/gogf/gf/v2](https://pkg.go.dev/github.com/gogf/gf/v2)
💖 Thanks all the contributors making GoFrame awesome! [[Contributors](https://github.com/gogf/gf/graphs/contributors)] 💖
<a href="https://github.com/gogf/gf/graphs/contributors">
<img src="https://goframe.org/img/contributors.svg" />
</a>
# License
`GoFrame` is licensed under the [MIT License](LICENSE), 100% free and open-source, forever.
# Part Of Users
- [Tencent](https://www.tencent.com/)
- [ZTE](https://www.zte.com.cn/china/)
- [Ant Financial Services](https://www.antfin.com/)
- [VIVO](https://www.vivo.com/)
- [MedLinker](https://www.medlinker.com/)
- [KuCoin](https://www.kucoin.io/)
- [LeYouJia](https://www.leyoujia.com/)
- [IGG](https://igg.com)
- [37](https://www.37.com)
- [XiMaLaYa](https://www.ximalaya.com)
- [ZYBang](https://www.zybang.com/)
> We list part of the users here, if your company or products are using `GoFrame`, please let us know [here](https://goframe.org/pages/viewpage.action?pageId=1114415).
# Contributors
This project exists thanks to all the people who contribute. [[Contributors](https://github.com/gogf/gf/graphs/contributors)].
<a href="https://github.com/gogf/gf/graphs/contributors"><img src="https://contributors-img.web.app/image?repo=gogf/gf" /></a>
# Donators
If you love `GoFrame`, why not [buy developer a cup of coffee](https://goframe.org/pages/viewpage.action?pageId=1115633)?
If you love `GoFrame`, why not [buy developer a cup of coffee](https://goframe.org/supportus/donate)?
# Sponsors
@ -101,5 +88,5 @@ We appreciate any kind of sponsorship for `GoFrame` development. If you've got s
# Thanks
<a href="https://www.jetbrains.com/?from=GoFrame"><img src="https://goframe.org/download/thumbnails/1114119/jetbrains.png" height="120" alt="JetBrains"/></a>
<a href="https://www.atlassian.com/?from=GoFrame"><img src="https://goframe.org/download/attachments/1114119/atlassian.jpg" height="120" alt="Atlassian"/></a>
<a href="https://www.jetbrains.com/?from=GoFrame"><img src="https://goframe.org/img/jetbrains.png" height="120" alt="JetBrains"/></a>
<a href="https://www.atlassian.com/?from=GoFrame"><img src="https://goframe.org/img/atlassian.jpg" height="120" alt="Atlassian"/></a>

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.8.0-beta
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.8.0-beta
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.0-beta
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.8.0-beta
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.8.0-beta
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.8.0
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.8.0
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.0
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.8.0
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.8.0
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.8.0
github.com/gogf/gf/v2 v2.8.0
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
github.com/olekukonko/tablewriter v0.0.5
golang.org/x/mod v0.17.0

View File

@ -217,7 +217,7 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
if !gfile.Exists(in.PackDst) {
// Remove the go file that is automatically packed resource.
defer func() {
_ = gfile.Remove(in.PackDst)
_ = gfile.RemoveFile(in.PackDst)
mlog.Printf(`remove the automatically generated resource go file: %s`, in.PackDst)
}()
}

View File

@ -8,6 +8,7 @@ package cmd
import (
"context"
"fmt"
"io"
"net/http"
"os"
@ -22,8 +23,12 @@ import (
)
const (
GitName = "gf-site"
BranchName = "gh-pages"
SiteFileName = GitName + "-" + BranchName
// DocURL is the download address of the document
DocURL = "https://github.com/gogf/gf/archive/refs/heads/gh-pages.zip"
DocURL = "https://github.com/gogf/" + GitName + "/archive/refs/heads/" + BranchName + ".zip"
)
var (
@ -70,12 +75,13 @@ func (c cDoc) Index(ctx context.Context, in cDocInput) (out *cDocOutput, err err
mlog.Print("Failed to download document:", err)
return
}
s := g.Server()
s.SetServerRoot(docs.DocDir)
s.SetPort(in.Port)
s.SetDumpRouterMap(false)
mlog.Printf("Access address http://127.0.0.1:%d", in.Port)
s.Run()
http.Handle("/", http.FileServer(http.Dir(docs.DocDir)))
mlog.Printf("Access address http://127.0.0.1:%d in %s", in.Port, docs.DocDir)
err = http.ListenAndServe(fmt.Sprintf(":%d", in.Port), nil)
if err != nil {
return nil, err
}
return
}
@ -89,7 +95,7 @@ type DocSetting struct {
// NewDocSetting new DocSetting
func NewDocSetting(ctx context.Context, in cDocInput) *DocSetting {
fileName := "gf-doc-md.zip"
fileName := SiteFileName + ".zip"
tempDir := in.Path
if tempDir == "" {
tempDir = gfile.Temp("goframe/docs")
@ -99,17 +105,17 @@ func NewDocSetting(ctx context.Context, in cDocInput) *DocSetting {
return &DocSetting{
TempDir: filepath.FromSlash(tempDir),
DocDir: filepath.FromSlash(path.Join(tempDir, "gf-gh-pages")),
DocDir: filepath.FromSlash(path.Join(tempDir, SiteFileName)),
DocURL: in.Proxy + DocURL,
DocZipFile: filepath.FromSlash(path.Join(tempDir, fileName)),
}
}
// Clean clean the temporary directory
// Clean cleans the temporary directory
func (d *DocSetting) Clean() error {
if _, err := os.Stat(d.TempDir); err == nil {
err = gfile.Remove(d.TempDir)
err = gfile.RemoveAll(d.TempDir)
if err != nil {
mlog.Print("Failed to delete temporary directory:", err)
return err
@ -168,7 +174,7 @@ func (d *DocSetting) DownloadDoc() error {
err := gcompress.UnZipFile(d.DocZipFile, d.TempDir)
if err != nil {
mlog.Print("Failed to unzip the file, please run again:", err)
gfile.Remove(d.DocZipFile)
_ = gfile.RemoveFile(d.DocZipFile)
return err
}

View File

@ -93,6 +93,12 @@ type (
)
func (c cRun) Index(ctx context.Context, in cRunInput) (out *cRunOutput, err error) {
if !gfile.Exists(in.File) {
mlog.Fatalf(`given file "%s" not found`, in.File)
}
if !gfile.IsFile(in.File) {
mlog.Fatalf(`given "%s" is not a file`, in.File)
}
// Necessary check.
if gproc.SearchBinary("go") == "" {
mlog.Fatalf(`command "go" not found in your environment, please install golang first to proceed this command`)
@ -205,7 +211,7 @@ func (app *cRunApp) End(ctx context.Context, sig os.Signal, outputPath string) {
mlog.Debugf("kill process error: %s", err.Error())
}
}
if err := gfile.Remove(outputPath); err != nil {
if err := gfile.RemoveFile(outputPath); err != nil {
mlog.Printf("delete binary file error: %s", err.Error())
} else {
mlog.Printf("deleted binary file: %s", outputPath)

View File

@ -192,7 +192,7 @@ func (c cUp) doUpgradeCLI(ctx context.Context) (err error) {
defer func() {
mlog.Printf(`new version cli binary is successfully installed to "%s"`, gfile.SelfPath())
mlog.Printf(`remove temporary buffer file "%s"`, localSaveFilePath)
_ = gfile.Remove(localSaveFilePath)
_ = gfile.RemoveFile(localSaveFilePath)
}()
// It fails if file not exist or its size is less than 1MB.

View File

@ -0,0 +1,50 @@
// 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 (
"path/filepath"
"testing"
"github.com/gogf/gf/cmd/gf/v2/internal/cmd/genpb"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/guid"
)
func TestGenPbIssue3882(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
outputPath = gfile.Temp(guid.S())
outputApiPath = filepath.Join(outputPath, "api")
outputCtrlPath = filepath.Join(outputPath, "controller")
protobufFolder = gtest.DataPath("issue", "3882")
in = genpb.CGenPbInput{
Path: protobufFolder,
OutputApi: outputApiPath,
OutputCtrl: outputCtrlPath,
}
err error
)
err = gfile.Mkdir(outputApiPath)
t.AssertNil(err)
err = gfile.Mkdir(outputCtrlPath)
t.AssertNil(err)
defer gfile.Remove(outputPath)
_, err = genpb.CGenPb{}.Pb(ctx, in)
t.AssertNil(err)
var (
genContent = gfile.GetContents(filepath.Join(outputApiPath, "issue3882.pb.go"))
exceptText = `dc:"Some comment on field with 'one' 'two' 'three' in the comment."`
)
t.Assert(gstr.Contains(genContent, exceptText), true)
})
}

View File

@ -128,7 +128,7 @@ func (c CGenCtrl) generateByWatchFile(watchFile, sdkPath string, sdkStdVersion,
return
}
}
defer gfile.Remove(flockFilePath)
defer gfile.RemoveFile(flockFilePath)
_ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
// check this updated file is an api file.

View File

@ -89,7 +89,7 @@ func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion(
if err = gfile.PutContents(moduleFilePath, gstr.TrimLeft(content)); err != nil {
return err
}
mlog.Printf(`generated: %s`, moduleFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(moduleFilePath))
}
if !gfile.Exists(moduleFilePathNew) {
content := gstr.ReplaceByMap(consts.TemplateGenCtrlControllerNewEmpty, g.MapStrStr{
@ -99,7 +99,7 @@ func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion(
if err = gfile.PutContents(moduleFilePathNew, gstr.TrimLeft(content)); err != nil {
return err
}
mlog.Printf(`generated: %s`, moduleFilePathNew)
mlog.Printf(`generated: %s`, gfile.RealPath(moduleFilePathNew))
}
filePaths, err := gfile.ScanDir(dstModuleFolderPath, "*.go", false)
if err != nil {
@ -161,7 +161,7 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite
return err
}
}
mlog.Printf(`generated: %s`, methodFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(methodFilePath))
return
}
@ -221,7 +221,7 @@ func (c *controllerGenerator) doGenerateCtrlMergeItem(dstModuleFolderPath string
if err = gfile.PutContentsAppend(ctrlFilePath, ctrlFileItem.controllers.String()); err != nil {
return err
}
mlog.Printf(`generated: %s`, ctrlFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(ctrlFilePath))
}
return
}

View File

@ -49,7 +49,7 @@ func (c *controllerClearer) doClear(dstModuleFolderPath string, item apiItem) (e
`remove unimplemented and of no api definitions controller file: %s`,
methodFilePath,
)
err = gfile.Remove(methodFilePath)
err = gfile.RemoveFile(methodFilePath)
}
}
return

View File

@ -94,7 +94,7 @@ func (c *apiInterfaceGenerator) doGenerate(apiModuleFolderPath string, module st
"{Interfaces}": gstr.TrimRightStr(interfaceDefinition, "\n", 2),
}))
err = gfile.PutContents(moduleFilePath, interfaceContent)
mlog.Printf(`generated: %s`, moduleFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(moduleFilePath))
return
}

View File

@ -65,7 +65,7 @@ func (c *apiSdkGenerator) doGenerateSdkPkgFile(sdkFolderPath string) (err error)
"{PkgName}": pkgName,
}))
err = gfile.PutContents(pkgFilePath, fileContent)
mlog.Printf(`generated: %s`, pkgFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(pkgFilePath))
return
}
@ -130,9 +130,9 @@ func (c *apiSdkGenerator) doGenerateSdkIClient(
if isDirty {
err = gfile.PutContents(iClientFilePath, fileContent)
if isExist {
mlog.Printf(`updated: %s`, iClientFilePath)
mlog.Printf(`updated: %s`, gfile.RealPath(iClientFilePath))
} else {
mlog.Printf(`generated: %s`, iClientFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(iClientFilePath))
}
}
return
@ -183,7 +183,7 @@ func (c *apiSdkGenerator) doGenerateSdkImplementer(
implementerFileContent += "\n"
}
err = gfile.PutContents(implementerFilePath, implementerFileContent)
mlog.Printf(`generated: %s`, implementerFilePath)
mlog.Printf(`generated: %s`, gfile.RealPath(implementerFilePath))
return
}

View File

@ -40,7 +40,7 @@ func doClearItem(item CGenDaoInternalGenItem, allGeneratedFilePaths []string) {
}
for _, filePath := range generatedFilePaths {
if !gstr.InArray(allGeneratedFilePaths, filePath) {
if err := gfile.Remove(filePath); err != nil {
if err := gfile.RemoveFile(filePath); err != nil {
mlog.Print(err)
}
}

View File

@ -123,7 +123,7 @@ func generateDaoIndex(in generateDaoIndexInput) {
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
} else {
utils.GoFmt(path)
mlog.Print("generated:", path)
mlog.Print("generated:", gfile.RealPath(path))
}
}
}
@ -157,7 +157,7 @@ func generateDaoInternal(in generateDaoInternalInput) {
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
} else {
utils.GoFmt(path)
mlog.Print("generated:", path)
mlog.Print("generated:", gfile.RealPath(path))
}
}

View File

@ -70,7 +70,7 @@ func generateDo(ctx context.Context, in CGenDaoInternalInput) {
mlog.Fatalf(`writing content to "%s" failed: %v`, doFilePath, err)
} else {
utils.GoFmt(doFilePath)
mlog.Print("generated:", doFilePath)
mlog.Print("generated:", gfile.RealPath(doFilePath))
}
}
}

View File

@ -55,7 +55,7 @@ func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
mlog.Fatalf("writing content to '%s' failed: %v", entityFilePath, err)
} else {
utils.GoFmt(entityFilePath)
mlog.Print("generated:", entityFilePath)
mlog.Print("generated:", gfile.RealPath(entityFilePath))
}
}
}

View File

@ -94,6 +94,9 @@ func (c CGenPb) Pb(ctx context.Context, in CGenPbInput) (out *CGenPbOutput, err
mlog.Fatalf(`no proto files found in folder "%s"`, in.Path)
}
var originPwd = gfile.Pwd()
defer gfile.Chdir(originPwd)
if err = gfile.Chdir(protoPath); err != nil {
mlog.Fatal(err)
}

View File

@ -12,6 +12,7 @@ import (
"github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
@ -90,8 +91,12 @@ func (c CGenPb) tagCommentIntoListMap(comment string, lineTagMap *gmap.ListMap)
lineTagMap.Set(tagName, lineTagMap.GetVar(tagName).String()+tagContent)
} else {
var (
tagName = "dc"
tagContent = comment
tagName = "dc"
// Convert backticks and double quotes to single quotes.
tagContent = gstr.ReplaceByMap(comment, g.MapStrStr{
"`": `'`,
`"`: `'`,
})
)
lineTagMap.Set(tagName, lineTagMap.GetVar(tagName).String()+tagContent)
}

View File

@ -254,7 +254,7 @@ func generatePbEntityContentFile(ctx context.Context, in CGenPbEntityInternalInp
if err := gfile.PutContents(path, strings.TrimSpace(entityContent)); err != nil {
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
} else {
mlog.Print("generated:", path)
mlog.Print("generated:", gfile.RealPath(path))
}
}

View File

@ -114,7 +114,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
return
}
}
defer gfile.Remove(flockFilePath)
defer gfile.RemoveFile(flockFilePath)
_ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
// It works only if given WatchFile is in SrcFolder.
@ -253,7 +253,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
utils.IsFileDoNotEdit(relativeFilePath) {
mlog.Printf(`remove no longer used service file: %s`, relativeFilePath)
if err = gfile.Remove(file); err != nil {
if err = gfile.RemoveFile(file); err != nil {
return nil, err
}
}

View File

@ -2,7 +2,7 @@ module github.com/gogf/gf/cmd/gf/cmd/gf/testdata/vardump/v2
go 1.18
require github.com/gogf/gf/v2 v2.8.0-beta
require github.com/gogf/gf/v2 v2.8.0
require (
go.opentelemetry.io/otel v1.24.0 // indirect

View File

@ -0,0 +1,10 @@
syntax = "proto3";
package test;
option go_package = "github.com/gogf/gf/cmd/gf/test";
message SomeMessage {
// Some comment on field with "one" `two` 'three' in the comment.
string field = 1;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/nacos/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
github.com/nacos-group/nacos-sdk-go/v2 v2.2.5
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/polaris/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
github.com/polarismesh/polaris-go v1.5.8
)

View File

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

View File

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

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/drivers/mssql/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
github.com/microsoft/go-mssqldb v1.7.1
)

View File

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

View File

@ -93,36 +93,17 @@ func Test_Table_Relation_With_Scan(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_score"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -291,36 +272,17 @@ func Test_Table_Relation_With(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -491,36 +453,17 @@ func Test_Table_Relation_WithAll(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -606,36 +549,17 @@ func Test_Table_Relation_WithAll_List(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -747,36 +671,17 @@ func Test_Table_Relation_WithAllCondition_List(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -883,36 +788,17 @@ func Test_Table_Relation_WithAll_Embedded_With_SelfMaintained_Attributes(t *test
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -998,36 +884,17 @@ func Test_Table_Relation_WithAll_Embedded_Without_SelfMaintained_Attributes(t *t
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -1121,36 +988,17 @@ func Test_Table_Relation_WithAll_Embedded_WithoutMeta(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -1237,36 +1085,17 @@ func Test_Table_Relation_WithAll_AttributeStructAlsoHasWithTag(t *testing.T) {
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -1353,36 +1182,17 @@ func Test_Table_Relation_WithAll_AttributeStructAlsoHasWithTag_MoreDeep(t *testi
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)
@ -1499,36 +1309,17 @@ func Test_Table_Relation_With_AttributeStructAlsoHasWithTag_MoreDeep(t *testing.
tableUserDetail = "user_detail"
tableUserScores = "user_scores"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user.sql"), tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_detail.sql"), tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserScores)); err != nil {
if _, err := db.Exec(ctx, fmt.Sprintf(gtest.DataContent("with_tpl_user_scores.sql"), tableUserScores)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserScores)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS %s (
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
address varchar(45) NOT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
uid int(10) unsigned NOT NULL,
score int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

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

View File

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

View File

@ -34,16 +34,12 @@ func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
source, _ = gregex.ReplaceString(`dbname=([\w\.\-]+)+`, "dbname="+config.Name, source)
}
} else {
source = fmt.Sprintf(
"user=%s password='%s' host=%s port=%s sslmode=disable",
config.User, config.Pass, config.Host, config.Port)
if config.Name != "" {
source = fmt.Sprintf(
"user=%s password=%s host=%s port=%s dbname=%s sslmode=disable",
config.User, config.Pass, config.Host, config.Port, config.Name,
)
} else {
source = fmt.Sprintf(
"user=%s password=%s host=%s port=%s sslmode=disable",
config.User, config.Pass, config.Host, config.Port,
)
source = fmt.Sprintf("%s dbname=%s", source, config.Name)
}
if config.Namespace != "" {

View File

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

View File

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

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/metric/otelmetric/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
github.com/prometheus/client_golang v1.19.1
go.opentelemetry.io/contrib/instrumentation/runtime v0.49.0
go.opentelemetry.io/otel v1.24.0

View File

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

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/etcd/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
go.etcd.io/etcd/client/v3 v3.5.7
google.golang.org/grpc v1.59.0
)

View File

@ -99,7 +99,7 @@ func (r *Registry) getServices(ctx context.Context) (services []gsvc.Service, er
`service "%s" is expired, update at: %s, current: %s, sub duration: %s`,
s.GetKey(), updateAt.String(), nowTime.String(), subDuration.String(),
)
_ = gfile.Remove(filePath)
_ = gfile.RemoveFile(filePath)
continue
}
services = append(services, s)

View File

@ -44,7 +44,7 @@ func (r *Registry) Register(ctx context.Context, service gsvc.Service) (register
// Deregister off-lines and removes `service` from the Registry.
func (r *Registry) Deregister(ctx context.Context, service gsvc.Service) error {
return gfile.Remove(r.getServiceFilePath(service))
return gfile.RemoveFile(r.getServiceFilePath(service))
}
func (r *Registry) getServiceFilePath(service gsvc.Service) string {

View File

@ -2,7 +2,7 @@ module github.com/gogf/gf/contrib/registry/file/v2
go 1.20
require github.com/gogf/gf/v2 v2.8.0-beta
require github.com/gogf/gf/v2 v2.8.0
require (
github.com/BurntSushi/toml v1.4.0 // indirect

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/nacos/v2
go 1.20
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
github.com/nacos-group/nacos-sdk-go/v2 v2.2.7
)

View File

@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/registry/polaris/v2
go 1.21
require (
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
github.com/polarismesh/polaris-go v1.5.8
)

View File

@ -4,7 +4,7 @@ go 1.20
require (
github.com/go-zookeeper/zk v1.0.3
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0
golang.org/x/sync v0.7.0
)

View File

@ -3,8 +3,8 @@ module github.com/gogf/gf/contrib/rpc/grpcx/v2
go 1.20
require (
github.com/gogf/gf/contrib/registry/file/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/contrib/registry/file/v2 v2.8.0
github.com/gogf/gf/v2 v2.8.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
google.golang.org/grpc v1.64.1

View File

@ -2,7 +2,7 @@ module github.com/gogf/gf/contrib/sdk/httpclient/v2
go 1.20
require github.com/gogf/gf/v2 v2.8.0-beta
require github.com/gogf/gf/v2 v2.8.0
require (
github.com/BurntSushi/toml v1.4.0 // indirect

View File

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

View File

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

View File

@ -259,6 +259,10 @@ func (c *Core) CheckLocalTypeForField(ctx context.Context, fieldType string, fie
if gstr.ContainsI(fieldType, "unsigned") {
return LocalTypeUint, nil
}
// field length is 1 means boolean.
if typePattern == "1" {
return LocalTypeBool, nil
}
return LocalTypeInt, nil
case

View File

@ -318,7 +318,7 @@ func (m *Model) parseWithTagInFieldStruct(field gstructs.Field) (output parseWit
array []string
key string
)
for _, v := range gstr.SplitAndTrim(ormTag, " ") {
for _, v := range gstr.SplitAndTrim(ormTag, ",") {
array = gstr.Split(v, ":")
if len(array) == 2 {
key = array[0]
@ -327,9 +327,6 @@ func (m *Model) parseWithTagInFieldStruct(field gstructs.Field) (output parseWit
data[key] += " " + gstr.Trim(v)
}
}
for k, v := range data {
data[k] = gstr.TrimRight(v, ",")
}
output.With = data[OrmTagForWith]
output.Where = data[OrmTagForWithWhere]
output.Order = data[OrmTagForWithOrder]

View File

@ -82,3 +82,25 @@ func ExampleIs() {
// true
// false
}
func ExampleCode() {
err1 := gerror.NewCode(gcode.CodeInternalError, "permission denied")
err2 := gerror.Wrap(err1, "operation failed")
fmt.Println(gerror.Code(err1))
fmt.Println(gerror.Code(err2))
// Output:
// 50:Internal Error
// 50:Internal Error
}
func ExampleHasCode() {
err1 := gerror.NewCode(gcode.CodeInternalError, "permission denied")
err2 := gerror.Wrap(err1, "operation failed")
fmt.Println(gerror.HasCode(err1, gcode.CodeOK))
fmt.Println(gerror.HasCode(err2, gcode.CodeInternalError))
// Output:
// false
// true
}

View File

@ -3,22 +3,22 @@ module github.com/gogf/gf/example
go 1.21
require (
github.com/gogf/gf/contrib/config/apollo/v2 v2.8.0-beta
github.com/gogf/gf/contrib/config/consul/v2 v2.8.0-beta
github.com/gogf/gf/contrib/config/kubecm/v2 v2.8.0-beta
github.com/gogf/gf/contrib/config/nacos/v2 v2.8.0-beta
github.com/gogf/gf/contrib/config/polaris/v2 v2.8.0-beta
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.0-beta
github.com/gogf/gf/contrib/metric/otelmetric/v2 v2.8.0-beta
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.0-beta
github.com/gogf/gf/contrib/registry/etcd/v2 v2.8.0-beta
github.com/gogf/gf/contrib/registry/file/v2 v2.8.0-beta
github.com/gogf/gf/contrib/registry/nacos/v2 v2.8.0-beta
github.com/gogf/gf/contrib/registry/polaris/v2 v2.8.0-beta
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.8.0-beta
github.com/gogf/gf/contrib/trace/otlpgrpc/v2 v2.8.0-beta
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.8.0-beta
github.com/gogf/gf/v2 v2.8.0-beta
github.com/gogf/gf/contrib/config/apollo/v2 v2.8.0
github.com/gogf/gf/contrib/config/consul/v2 v2.8.0
github.com/gogf/gf/contrib/config/kubecm/v2 v2.8.0
github.com/gogf/gf/contrib/config/nacos/v2 v2.8.0
github.com/gogf/gf/contrib/config/polaris/v2 v2.8.0
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.0
github.com/gogf/gf/contrib/metric/otelmetric/v2 v2.8.0
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.0
github.com/gogf/gf/contrib/registry/etcd/v2 v2.8.0
github.com/gogf/gf/contrib/registry/file/v2 v2.8.0
github.com/gogf/gf/contrib/registry/nacos/v2 v2.8.0
github.com/gogf/gf/contrib/registry/polaris/v2 v2.8.0
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.8.0
github.com/gogf/gf/contrib/trace/otlpgrpc/v2 v2.8.0
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.8.0
github.com/gogf/gf/v2 v2.8.0
github.com/hashicorp/consul/api v1.24.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/nacos-group/nacos-sdk-go/v2 v2.2.7

View File

@ -84,17 +84,13 @@ func New() *Client {
func (c *Client) Clone() *Client {
newClient := New()
*newClient = *c
if len(c.header) > 0 {
newClient.header = make(map[string]string)
for k, v := range c.header {
newClient.header[k] = v
}
newClient.header = make(map[string]string, len(c.header))
for k, v := range c.header {
newClient.header[k] = v
}
if len(c.cookies) > 0 {
newClient.cookies = make(map[string]string)
for k, v := range c.cookies {
newClient.cookies[k] = v
}
newClient.cookies = make(map[string]string, len(c.cookies))
for k, v := range c.cookies {
newClient.cookies[k] = v
}
return newClient
}

View File

@ -177,6 +177,40 @@ func Test_Client_Chain_Header(t *testing.T) {
t.Assert(c.HeaderRaw("test1: 1234567890\ntest2: abcdefg").GetContent(ctx, "/header1"), "1234567890")
t.Assert(c.HeaderRaw("test1: 1234567890\ntest2: abcdefg").GetContent(ctx, "/header2"), "abcdefg")
})
gtest.C(t, func(t *gtest.T) {
c := g.Client()
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
t.Assert(c.GetContent(ctx, "/header1"), "")
copyWithHeader := c.Header(g.MapStrStr{"test1": "1234567890"})
t.Assert(copyWithHeader.GetContent(ctx, "/header1"), "1234567890")
t.Assert(c.GetContent(ctx, "/header1"), "")
})
}
func Test_Client_Chain_Cookie(t *testing.T) {
s := g.Server(guid.S())
s.BindHandler("/cookie", func(r *ghttp.Request) {
r.Response.Write(r.Cookie.Get("test", "def"))
})
s.SetDumpRouterMap(false)
s.Start()
defer s.Shutdown()
time.Sleep(100 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
c := g.Client()
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
t.Assert(c.GetContent(ctx, "/cookie"), "def")
copyWithCookie := c.Cookie(g.MapStrStr{"test": "1234567890"})
t.Assert(copyWithCookie.GetContent(ctx, "/cookie"), "1234567890")
t.Assert(c.GetContent(ctx, "/cookie"), "def")
})
}
func Test_Client_Chain_Context(t *testing.T) {

View File

@ -221,28 +221,6 @@ func (s *Server) checkAndCreateFuncInfo(
}
*/
// The request struct should be named as `xxxReq`.
reqStructName := trimGeneric(reflectType.In(1).String())
if !gstr.HasSuffix(reqStructName, `Req`) {
err = gerror.NewCodef(
gcode.CodeInvalidParameter,
`invalid struct naming for request: defined as "%s", but it should be named with "Req" suffix like "XxxReq"`,
reqStructName,
)
return
}
// The response struct should be named as `xxxRes`.
resStructName := trimGeneric(reflectType.Out(0).String())
if !gstr.HasSuffix(resStructName, `Res`) {
err = gerror.NewCodef(
gcode.CodeInvalidParameter,
`invalid struct naming for response: defined as "%s", but it should be named with "Res" suffix like "XxxRes"`,
resStructName,
)
return
}
funcInfo.IsStrictRoute = true
inputObject = reflect.New(funcInfo.Type.In(1).Elem())

View File

@ -252,6 +252,10 @@ func Glob(pattern string, onlyNames ...bool) ([]string, error) {
// If parameter `path` is directory, it deletes it recursively.
//
// It does nothing if given `path` does not exist or is empty.
//
// Deprecated:
// As the name Remove for files deleting is ambiguous,
// please use RemoveFile or RemoveAll for explicit usage instead.
func Remove(path string) (err error) {
// It does nothing if `path` is empty.
if path == "" {
@ -263,6 +267,25 @@ func Remove(path string) (err error) {
return
}
// RemoveFile removes the named file or (empty) directory.
func RemoveFile(path string) (err error) {
if err = os.Remove(path); err != nil {
err = gerror.Wrapf(err, `os.Remove failed for path "%s"`, path)
}
return
}
// RemoveAll removes path and any children it contains.
// It removes everything it can but returns the first error
// it encounters. If the path does not exist, RemoveAll
// returns nil (no error).
func RemoveAll(path string) (err error) {
if err = os.RemoveAll(path); err != nil {
err = gerror.Wrapf(err, `os.RemoveAll failed for path "%s"`, path)
}
return
}
// IsReadable checks whether given `path` is readable.
func IsReadable(path string) bool {
result := true
@ -270,7 +293,9 @@ func IsReadable(path string) bool {
if err != nil {
result = false
}
file.Close()
if file != nil {
_ = file.Close()
}
return result
}
@ -294,7 +319,9 @@ func IsWritable(path string) bool {
if err != nil {
result = false
}
_ = file.Close()
if file != nil {
_ = file.Close()
}
}
return result
}
@ -406,15 +433,17 @@ func IsEmpty(path string) bool {
if err != nil {
return true
}
if file == nil {
return true
}
defer file.Close()
names, err := file.Readdirnames(-1)
if err != nil {
return true
}
return len(names) == 0
} else {
return stat.Size() == 0
}
return stat.Size() == 0
}
// Ext returns the file name extension used by path.

View File

@ -16,6 +16,7 @@ import (
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/guid"
)
func Test_IsDir(t *testing.T) {
@ -213,7 +214,6 @@ func Test_OpenWithFlagPerm(t *testing.T) {
}
func Test_Exists(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
flag bool
@ -685,3 +685,43 @@ func Test_MTimestamp(t *testing.T) {
t.Assert(gfile.MTimestamp(gfile.Temp()) > 0, true)
})
}
func Test_RemoveFile_RemoveAll(t *testing.T) {
// safe deleting single file.
gtest.C(t, func(t *gtest.T) {
path := gfile.Temp(guid.S())
err := gfile.PutContents(path, "1")
t.AssertNil(err)
t.Assert(gfile.Exists(path), true)
err = gfile.RemoveFile(path)
t.AssertNil(err)
t.Assert(gfile.Exists(path), false)
})
// error deleting dir which is not empty.
gtest.C(t, func(t *gtest.T) {
var (
err error
dirPath = gfile.Temp(guid.S())
filePath1 = gfile.Join(dirPath, guid.S())
filePath2 = gfile.Join(dirPath, guid.S())
)
err = gfile.PutContents(filePath1, "1")
t.AssertNil(err)
t.Assert(gfile.Exists(filePath1), true)
err = gfile.PutContents(filePath2, "2")
t.AssertNil(err)
t.Assert(gfile.Exists(filePath2), true)
err = gfile.RemoveFile(dirPath)
t.AssertNE(err, nil)
t.Assert(gfile.Exists(filePath1), true)
t.Assert(gfile.Exists(filePath2), true)
err = gfile.RemoveAll(dirPath)
t.AssertNil(err)
t.Assert(gfile.Exists(filePath1), false)
t.Assert(gfile.Exists(filePath2), false)
})
}

View File

@ -55,7 +55,7 @@ func (l *Logger) doRotateFile(ctx context.Context, filePath string) error {
// No backups, it then just removes the current logging file.
if l.config.RotateBackupLimit == 0 {
if err := gfile.Remove(filePath); err != nil {
if err := gfile.RemoveFile(filePath); err != nil {
return err
}
intlog.Printf(
@ -216,7 +216,7 @@ func (l *Logger) rotateChecksTimely(ctx context.Context) {
err := gcompress.GzipFile(path, path+".gz")
if err == nil {
intlog.Printf(ctx, `compressed done, remove original logging file: %s`, path)
if err = gfile.Remove(path); err != nil {
if err = gfile.RemoveFile(path); err != nil {
intlog.Print(ctx, err)
}
} else {
@ -264,7 +264,7 @@ func (l *Logger) rotateChecksTimely(ctx context.Context) {
for i := 0; i < diff; i++ {
path, _ := backupFiles.PopLeft()
intlog.Printf(ctx, `remove exceeded backup limit file: %s`, path)
if err := gfile.Remove(path.(string)); err != nil {
if err = gfile.RemoveFile(path.(string)); err != nil {
intlog.Errorf(ctx, `%+v`, err)
}
}
@ -284,7 +284,7 @@ func (l *Logger) rotateChecksTimely(ctx context.Context) {
`%v - %v = %v > %v, remove expired backup file: %s`,
now, mtime, subDuration, l.config.RotateBackupExpire, path,
)
if err := gfile.Remove(path); err != nil {
if err = gfile.RemoveFile(path); err != nil {
intlog.Errorf(ctx, `%+v`, err)
}
return true

View File

@ -128,7 +128,7 @@ func (s *StorageFile) sessionFilePath(sessionId string) string {
// RemoveAll deletes all key-value pairs from storage.
func (s *StorageFile) RemoveAll(ctx context.Context, sessionId string) error {
return gfile.Remove(s.sessionFilePath(sessionId))
return gfile.RemoveAll(s.sessionFilePath(sessionId))
}
// GetSession returns the session data as *gmap.StrAnyMap for given session id from storage.
@ -262,7 +262,7 @@ func (s *StorageFile) checkAndClearSessionFile(ctx context.Context, path string)
path, gtime.NewFromTimeStamp(fileTimestampMilli), s.ttl,
)
})
return gfile.Remove(path)
return gfile.RemoveFile(path)
}
return nil
}

View File

@ -315,35 +315,44 @@ func compareMap(value, expect interface{}) error {
rvValue = reflect.ValueOf(value)
rvExpect = reflect.ValueOf(expect)
)
if rvExpect.Kind() == reflect.Map {
if rvValue.Kind() == reflect.Map {
if rvExpect.Len() == rvValue.Len() {
// Turn two interface maps to the same type for comparison.
// Direct use of rvValue.MapIndex(key).Interface() will panic
// when the key types are inconsistent.
mValue := make(map[string]string)
mExpect := make(map[string]string)
ksValue := rvValue.MapKeys()
ksExpect := rvExpect.MapKeys()
for _, key := range ksValue {
mValue[gconv.String(key.Interface())] = gconv.String(rvValue.MapIndex(key).Interface())
}
for _, key := range ksExpect {
mExpect[gconv.String(key.Interface())] = gconv.String(rvExpect.MapIndex(key).Interface())
}
for k, v := range mExpect {
if v != mValue[k] {
return fmt.Errorf(`[ASSERT] EXPECT VALUE map["%v"]:%v == map["%v"]:%v`+
"\nGIVEN : %v\nEXPECT: %v", k, mValue[k], k, v, mValue, mExpect)
}
}
} else {
return fmt.Errorf(`[ASSERT] EXPECT MAP LENGTH %d == %d`, rvValue.Len(), rvExpect.Len())
}
} else {
return fmt.Errorf(`[ASSERT] EXPECT VALUE TO BE A MAP, BUT GIVEN "%s"`, rvValue.Kind())
if rvExpect.Kind() != reflect.Map {
return nil
}
if rvValue.Kind() != reflect.Map {
return fmt.Errorf(`[ASSERT] EXPECT VALUE TO BE A MAP, BUT GIVEN "%s"`, rvValue.Kind())
}
if rvExpect.Len() != rvValue.Len() {
return fmt.Errorf(`[ASSERT] EXPECT MAP LENGTH %d == %d`, rvValue.Len(), rvExpect.Len())
}
// Turn two interface maps to the same type for comparison.
// Direct use of rvValue.MapIndex(key).Interface() will panic
// when the key types are inconsistent.
var (
mValue = make(map[string]string)
mExpect = make(map[string]string)
ksValue = rvValue.MapKeys()
ksExpect = rvExpect.MapKeys()
)
for _, key := range ksValue {
mValue[gconv.String(key.Interface())] = gconv.String(rvValue.MapIndex(key).Interface())
}
for _, key := range ksExpect {
mExpect[gconv.String(key.Interface())] = gconv.String(rvExpect.MapIndex(key).Interface())
}
for k, v := range mExpect {
if v != mValue[k] {
return fmt.Errorf(`[ASSERT] EXPECT VALUE map["%v"]:%v == map["%v"]:%v`+
"\nGIVEN : %v\nEXPECT: %v", k, mValue[k], k, v, mValue, mExpect)
}
}
return nil
}
@ -364,9 +373,9 @@ func AssertNil(value interface{}) {
// which will be joined with current system separator and returned with the path.
func DataPath(names ...string) string {
_, path, _ := gdebug.CallerWithFilter([]string{pathFilterKey})
path = filepath.Dir(path) + "/testdata"
path = filepath.Join(filepath.Dir(path), "testdata")
for _, name := range names {
path += "/" + name
path = filepath.Join(path, name)
}
return filepath.FromSlash(path)
}

View File

@ -399,7 +399,7 @@ func TestAssertError(t *testing.T) {
func TestDataPath(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
t.Assert(filepath.ToSlash(gtest.DataPath("testdata.txt")), `./testdata/testdata.txt`)
t.Assert(filepath.ToSlash(gtest.DataPath("testdata.txt")), `testdata/testdata.txt`)
})
}

View File

@ -125,6 +125,9 @@ func Int64(any interface{}) int64 {
if valueInt64 := Float64(s); math.IsNaN(valueInt64) {
return 0
} else {
if isMinus {
return -int64(valueInt64)
}
return int64(valueInt64)
}
default:

View File

@ -220,12 +220,6 @@ func doStruct(
if len(usedParamsKeyOrTagNameMap) == len(paramsMap) {
return nil
}
// If the length of `paramsMap` is less than the number of fields, then loop based on `paramsMap`
if len(paramsMap) < len(cachedStructInfo.FieldConvertInfos) {
return bindStructWithLoopParamsMap(
paramsMap, pointerElemReflectValue, paramKeyToAttrMap, usedParamsKeyOrTagNameMap, cachedStructInfo,
)
}
return bindStructWithLoopFieldInfos(
paramsMap, pointerElemReflectValue, paramKeyToAttrMap, usedParamsKeyOrTagNameMap, cachedStructInfo,
)
@ -247,84 +241,6 @@ func setOtherSameNameField(
return nil
}
func bindStructWithLoopParamsMap(
paramsMap map[string]any,
structValue reflect.Value,
paramKeyToAttrMap map[string]string,
usedParamsKeyOrTagNameMap map[string]struct{},
cachedStructInfo *structcache.CachedStructInfo,
) (err error) {
var (
fieldName string
cachedFieldInfo *structcache.CachedFieldInfo
fieldValue reflect.Value
paramKey string
paramValue any
ok bool
)
for paramKey, paramValue = range paramsMap {
if _, ok = usedParamsKeyOrTagNameMap[paramKey]; ok {
continue
}
cachedFieldInfo = cachedStructInfo.GetFieldInfo(paramKey)
if cachedFieldInfo != nil {
fieldName = cachedFieldInfo.FieldName()
// already converted using its field name?
// the field name has the more priority than tag name.
_, ok = usedParamsKeyOrTagNameMap[fieldName]
if ok && cachedFieldInfo.IsField {
continue
}
fieldValue = cachedFieldInfo.GetFieldReflectValueFrom(structValue)
if err = bindVarToStructField(
fieldValue, paramValue, cachedFieldInfo, paramKeyToAttrMap,
); err != nil {
return err
}
// handle same field name in nested struct.
if len(cachedFieldInfo.OtherSameNameField) > 0 {
if err = setOtherSameNameField(cachedFieldInfo, paramValue, structValue, paramKeyToAttrMap); err != nil {
return err
}
}
usedParamsKeyOrTagNameMap[fieldName] = struct{}{}
continue
}
// fuzzy matching.
for _, cachedFieldInfo = range cachedStructInfo.FieldConvertInfos {
fieldName = cachedFieldInfo.FieldName()
if _, ok = usedParamsKeyOrTagNameMap[fieldName]; ok {
continue
}
if !strings.EqualFold(
cachedFieldInfo.RemoveSymbolsFieldName,
utils.RemoveSymbols(paramKey)) {
continue
}
fieldValue = cachedFieldInfo.GetFieldReflectValueFrom(structValue)
if paramValue != nil {
if err = bindVarToStructField(
fieldValue, paramValue, cachedFieldInfo, paramKeyToAttrMap,
); err != nil {
return err
}
// handle same field name in nested struct.
if len(cachedFieldInfo.OtherSameNameField) > 0 {
if err = setOtherSameNameField(
cachedFieldInfo, paramValue, structValue, paramKeyToAttrMap,
); err != nil {
return err
}
}
}
usedParamsKeyOrTagNameMap[cachedFieldInfo.FieldName()] = struct{}{}
break
}
}
return nil
}
func bindStructWithLoopFieldInfos(
paramsMap map[string]any,
structValue reflect.Value,
@ -346,10 +262,6 @@ func bindStructWithLoopFieldInfos(
if paramValue, ok = paramsMap[fieldTag]; !ok {
continue
}
if _, ok = usedParamsKeyOrTagNameMap[fieldTag]; ok {
matched = true
break
}
fieldValue = cachedFieldInfo.GetFieldReflectValueFrom(structValue)
if err = bindVarToStructField(
fieldValue, paramValue, cachedFieldInfo, paramKeyToAttrMap,

View File

@ -69,6 +69,7 @@ var intTests = []struct {
{"0XA", 10, 10, 10, 10, 10},
{"-0XA", -10, -10, -10, -10, -10},
{"123.456", 123, 123, 123, 123, 123},
{"-123.456", -123, -123, -123, -123, -123},
{"true", 0, 0, 0, 0, 0},
{"false", 0, 0, 0, 0, 0},
{"on", 0, 0, 0, 0, 0},

View File

@ -13,6 +13,7 @@ import (
"time"
"github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/internal/json"
@ -783,3 +784,24 @@ func Test_Issue3868(t *testing.T) {
}
})
}
// https://github.com/gogf/gf/issues/3903
func Test_Issue3903(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
type TestA struct {
UserId int `json:"UserId" orm:"user_id" `
}
type TestB struct {
TestA
UserId int `json:"NewUserId" description:""`
}
var input = map[string]interface{}{
"user_id": gvar.New(100, true),
}
var a TestB
err := gconv.StructTag(input, &a, "orm")
t.AssertNil(err)
t.Assert(a.TestA.UserId, 100)
t.Assert(a.UserId, 100)
})
}

View File

@ -59,16 +59,17 @@ func (csi *CachedStructInfo) AddField(field reflect.StructField, fieldIndexes []
}
func (csi *CachedStructInfo) makeOrCopyCachedInfo(
field reflect.StructField,
fieldIndexes []int,
priorityTags []string,
field reflect.StructField, fieldIndexes []int, priorityTags []string,
cachedFieldInfo *CachedFieldInfo,
currTagOrFieldName string,
) (newFieldInfo *CachedFieldInfo) {
if cachedFieldInfo == nil {
// If the field is not cached, it creates a new one.
newFieldInfo = csi.makeCachedFieldInfo(field, fieldIndexes, priorityTags)
} else if cachedFieldInfo.StructField.Type != field.Type {
newFieldInfo.IsField = currTagOrFieldName == field.Name
return
}
if cachedFieldInfo.StructField.Type != field.Type {
// If the types are different, some information needs to be reset.
newFieldInfo = csi.makeCachedFieldInfo(field, fieldIndexes, priorityTags)
} else {

View File

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