mirror of
https://gitee.com/johng/gf
synced 2026-06-12 04:03:22 +08:00
Compare commits
34 Commits
v2.8.0-bet
...
contrib/dr
| Author | SHA1 | Date | |
|---|---|---|---|
| 455830b842 | |||
| e56371e7c9 | |||
| eb8024913d | |||
| ee3eb8d48c | |||
| 15f94975db | |||
| 3797d0eee4 | |||
| e9ce1bde87 | |||
| 9c8b21af7b | |||
| 90851881cc | |||
| 3090fe7f4e | |||
| 0d1aed0741 | |||
| 910703ec3a | |||
| ec6c537def | |||
| bcfcda793c | |||
| 138dea0f3a | |||
| 3d4904eb3d | |||
| 955a76cf35 | |||
| ffa6081471 | |||
| 6baf4338b0 | |||
| 8c6db247b2 | |||
| fff2f8a24c | |||
| 475e8bbae0 | |||
| 070efecc6e | |||
| a63af5d5f8 | |||
| bd2e8408e8 | |||
| 6c6fd7902a | |||
| 1b7b536d6c | |||
| 9cc1cf1b53 | |||
| 76948d93d6 | |||
| 5ba165a3c0 | |||
| f4db846633 | |||
| e7cc2c3d9c | |||
| 01cd0103e4 | |||
| d1872f17f7 |
14
.github/workflows/ci-main.yml
vendored
14
.github/workflows/ci-main.yml
vendored
@ -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
|
||||
|
||||
45
README.MD
45
README.MD
@ -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"/>
|
||||
|
||||
[](https://pkg.go.dev/github.com/gogf/gf/v2)
|
||||
[](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>
|
||||
|
||||
@ -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.1
|
||||
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/drivers/oracle/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.8.1
|
||||
github.com/gogf/gf/v2 v2.8.1
|
||||
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
golang.org/x/mod v0.17.0
|
||||
|
||||
@ -138,11 +138,6 @@ type cBuildInput struct {
|
||||
type cBuildOutput struct{}
|
||||
|
||||
func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, err error) {
|
||||
// print used go env
|
||||
if in.DumpENV {
|
||||
_, _ = Env.Index(ctx, cEnvInput{})
|
||||
}
|
||||
|
||||
mlog.SetHeaderPrint(true)
|
||||
|
||||
mlog.Debugf(`build command input: %+v`, in)
|
||||
@ -217,7 +212,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)
|
||||
}()
|
||||
}
|
||||
@ -241,6 +236,10 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
|
||||
} else {
|
||||
genv.MustSet("CGO_ENABLED", "0")
|
||||
}
|
||||
// print used go env
|
||||
if in.DumpENV {
|
||||
_, _ = Env.Index(ctx, cEnvInput{})
|
||||
}
|
||||
for system, item := range platformMap {
|
||||
if len(customSystems) > 0 && customSystems[0] != "all" && !gstr.InArray(customSystems, system) {
|
||||
continue
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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.
|
||||
|
||||
50
cmd/gf/internal/cmd/cmd_z_unit_gen_pb_test.go
Normal file
50
cmd/gf/internal/cmd/cmd_z_unit_gen_pb_test.go
Normal 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)
|
||||
})
|
||||
}
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.1
|
||||
|
||||
require (
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
|
||||
10
cmd/gf/internal/cmd/testdata/issue/3882/issue3882.proto
vendored
Normal file
10
cmd/gf/internal/cmd/testdata/issue/3882/issue3882.proto
vendored
Normal 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
@ -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.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -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.1
|
||||
github.com/hashicorp/consul/api v1.24.0
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||
)
|
||||
|
||||
@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/kubecm/v2
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/gogf/gf/v2 v2.8.0-beta
|
||||
github.com/gogf/gf/v2 v2.8.1
|
||||
k8s.io/api v0.27.4
|
||||
k8s.io/apimachinery v0.27.4
|
||||
k8s.io/client-go v0.27.4
|
||||
|
||||
@ -3,7 +3,7 @@ module github.com/gogf/gf/contrib/config/nacos/v2
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/gogf/gf/v2 v2.8.0-beta
|
||||
github.com/gogf/gf/v2 v2.8.1
|
||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.5
|
||||
)
|
||||
|
||||
|
||||
@ -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.1
|
||||
github.com/polarismesh/polaris-go v1.5.8
|
||||
)
|
||||
|
||||
|
||||
@ -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.1
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/shopspring/decimal v1.3.1
|
||||
)
|
||||
|
||||
@ -6,7 +6,7 @@ replace github.com/gogf/gf/v2 => ../../../
|
||||
|
||||
require (
|
||||
gitee.com/chunanyong/dm v1.8.12
|
||||
github.com/gogf/gf/v2 v2.8.0-beta
|
||||
github.com/gogf/gf/v2 v2.8.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -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.1
|
||||
github.com/microsoft/go-mssqldb v1.7.1
|
||||
)
|
||||
|
||||
|
||||
@ -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.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
package mysql_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
@ -14,7 +15,7 @@ import (
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
)
|
||||
|
||||
func Test_Insert_Raw(t *testing.T) {
|
||||
func Test_Raw_Insert(t *testing.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
|
||||
@ -33,7 +34,7 @@ func Test_Insert_Raw(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_BatchInsert_Raw(t *testing.T) {
|
||||
func Test_Raw_BatchInsert(t *testing.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
|
||||
@ -63,7 +64,7 @@ func Test_BatchInsert_Raw(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Update_Raw(t *testing.T) {
|
||||
func Test_Raw_Update(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
@ -84,3 +85,45 @@ func Test_Update_Raw(t *testing.T) {
|
||||
t.Assert(n, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Raw_Where(t *testing.T) {
|
||||
table1 := createTable("Test_Raw_Where_Table1")
|
||||
table2 := createTable("Test_Raw_Where_Table2")
|
||||
defer dropTable(table1)
|
||||
defer dropTable(table2)
|
||||
|
||||
// https://github.com/gogf/gf/issues/3922
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
expectSql := "SELECT * FROM `Test_Raw_Where_Table1` AS A WHERE NOT EXISTS (SELECT B.id FROM `Test_Raw_Where_Table2` AS B WHERE `B`.`id`=A.id) LIMIT 1"
|
||||
sql, err := gdb.ToSQL(ctx, func(ctx context.Context) error {
|
||||
s := db.Model(table2).As("B").Ctx(ctx).Fields("B.id").Where("B.id", gdb.Raw("A.id"))
|
||||
m := db.Model(table1).As("A").Ctx(ctx).Where("NOT EXISTS ?", s).Limit(1)
|
||||
_, err := m.All()
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
t.Assert(expectSql, sql)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
expectSql := "SELECT * FROM `Test_Raw_Where_Table1` AS A WHERE NOT EXISTS (SELECT B.id FROM `Test_Raw_Where_Table2` AS B WHERE B.id=A.id) LIMIT 1"
|
||||
sql, err := gdb.ToSQL(ctx, func(ctx context.Context) error {
|
||||
s := db.Model(table2).As("B").Ctx(ctx).Fields("B.id").Where(gdb.Raw("B.id=A.id"))
|
||||
m := db.Model(table1).As("A").Ctx(ctx).Where("NOT EXISTS ?", s).Limit(1)
|
||||
_, err := m.All()
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
t.Assert(expectSql, sql)
|
||||
})
|
||||
// https://github.com/gogf/gf/issues/3915
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
expectSql := "SELECT * FROM `Test_Raw_Where_Table1` WHERE `passport` < `nickname`"
|
||||
sql, err := gdb.ToSQL(ctx, func(ctx context.Context) error {
|
||||
m := db.Model(table1).Ctx(ctx).WhereLT("passport", gdb.Raw("`nickname`"))
|
||||
_, err := m.All()
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
t.Assert(expectSql, sql)
|
||||
})
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -1345,3 +1345,35 @@ func Test_Issue3626(t *testing.T) {
|
||||
t.Assert(count, 1)
|
||||
})
|
||||
}
|
||||
|
||||
// https://github.com/gogf/gf/issues/3932
|
||||
func Test_Issue3932(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
one, err := db.Model(table).Order("id", "desc").One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["id"], 10)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
one, err := db.Model(table).Order("id desc").One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["id"], 10)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
one, err := db.Model(table).Order("id desc, nickname asc").One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["id"], 10)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
one, err := db.Model(table).Order("id desc", "nickname asc").One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["id"], 10)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
one, err := db.Model(table).Order("id desc").Order("nickname asc").One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["id"], 10)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1293,7 +1293,7 @@ func Test_Model_OrderBy(t *testing.T) {
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Model(table).Order("NULL").All()
|
||||
result, err := db.Model(table).Order(gdb.Raw("NULL")).All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), TableSize)
|
||||
t.Assert(result[0]["nickname"].String(), "name_1")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
5
contrib/drivers/mysql/testdata/with_tpl_user.sql
vendored
Normal file
5
contrib/drivers/mysql/testdata/with_tpl_user.sql
vendored
Normal 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;
|
||||
5
contrib/drivers/mysql/testdata/with_tpl_user_detail.sql
vendored
Normal file
5
contrib/drivers/mysql/testdata/with_tpl_user_detail.sql
vendored
Normal 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;
|
||||
6
contrib/drivers/mysql/testdata/with_tpl_user_scores.sql
vendored
Normal file
6
contrib/drivers/mysql/testdata/with_tpl_user_scores.sql
vendored
Normal 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;
|
||||
@ -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.1
|
||||
github.com/sijms/go-ora/v2 v2.7.10
|
||||
)
|
||||
|
||||
|
||||
@ -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.1
|
||||
github.com/lib/pq v1.10.9
|
||||
)
|
||||
|
||||
|
||||
@ -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 != "" {
|
||||
|
||||
@ -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.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@ -1431,7 +1431,7 @@ func Test_Model_OrderBy(t *testing.T) {
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Model(table).Order("NULL").All()
|
||||
result, err := db.Model(table).Order(gdb.Raw("NULL")).All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), TableSize)
|
||||
t.Assert(result[0]["nickname"].String(), "name_1")
|
||||
|
||||
@ -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.1
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
)
|
||||
|
||||
|
||||
@ -1390,7 +1390,7 @@ func Test_Model_OrderBy(t *testing.T) {
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Model(table).Order("NULL").All()
|
||||
result, err := db.Model(table).Order(gdb.Raw("NULL")).All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), TableSize)
|
||||
t.Assert(result[0]["nickname"].String(), "name_1")
|
||||
|
||||
@ -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.1
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.49.0
|
||||
go.opentelemetry.io/otel v1.24.0
|
||||
|
||||
@ -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.1
|
||||
github.com/redis/go-redis/v9 v9.2.1
|
||||
go.opentelemetry.io/otel v1.24.0
|
||||
go.opentelemetry.io/otel/trace v1.24.0
|
||||
|
||||
@ -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.1
|
||||
go.etcd.io/etcd/client/v3 v3.5.7
|
||||
google.golang.org/grpc v1.59.0
|
||||
)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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.1
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
|
||||
@ -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.1
|
||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.7
|
||||
)
|
||||
|
||||
|
||||
@ -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.1
|
||||
github.com/polarismesh/polaris-go v1.5.8
|
||||
)
|
||||
|
||||
|
||||
@ -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.1
|
||||
golang.org/x/sync v0.7.0
|
||||
)
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ func (r *Registry) Register(_ context.Context, service gsvc.Service) (gsvc.Servi
|
||||
// Deregister off-lines and removes `service` from the Registry.
|
||||
func (r *Registry) Deregister(ctx context.Context, service gsvc.Service) error {
|
||||
ch := make(chan error, 1)
|
||||
prefix := strings.TrimPrefix(strings.ReplaceAll(service.GetPrefix(), "/", "-"), "-")
|
||||
prefix := strings.Trim(strings.ReplaceAll(service.GetPrefix(), "/", "-"), "-")
|
||||
servicePath := path.Join(r.opts.namespace, prefix, service.GetName())
|
||||
go func() {
|
||||
err := r.conn.Delete(servicePath, -1)
|
||||
|
||||
@ -66,7 +66,7 @@ func (w *watcher) Proceed() ([]gsvc.Service, error) {
|
||||
}
|
||||
|
||||
func (w *watcher) getServicesByPrefix() ([]gsvc.Service, error) {
|
||||
prefix := strings.TrimPrefix(strings.ReplaceAll(w.prefix, "/", "-"), "-")
|
||||
prefix := strings.Trim(strings.ReplaceAll(w.prefix, "/", "-"), "-")
|
||||
serviceNamePath := path.Join(w.nameSpace, prefix)
|
||||
instances, err, _ := w.group.Do(serviceNamePath, func() (interface{}, error) {
|
||||
servicesID, _, err := w.conn.Children(serviceNamePath)
|
||||
@ -122,7 +122,7 @@ func (w *watcher) Close() error {
|
||||
}
|
||||
|
||||
func (w *watcher) watch(ctx context.Context) {
|
||||
prefix := strings.TrimPrefix(strings.ReplaceAll(w.prefix, "/", "-"), "-")
|
||||
prefix := strings.Trim(strings.ReplaceAll(w.prefix, "/", "-"), "-")
|
||||
serviceNamePath := path.Join(w.nameSpace, prefix)
|
||||
for {
|
||||
|
||||
|
||||
@ -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.1
|
||||
github.com/gogf/gf/v2 v2.8.1
|
||||
go.opentelemetry.io/otel v1.24.0
|
||||
go.opentelemetry.io/otel/trace v1.24.0
|
||||
google.golang.org/grpc v1.64.1
|
||||
|
||||
@ -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.1
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
|
||||
@ -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.1
|
||||
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
|
||||
|
||||
@ -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.1
|
||||
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
|
||||
|
||||
@ -15,28 +15,42 @@ import (
|
||||
|
||||
// Order sets the "ORDER BY" statement for the model.
|
||||
//
|
||||
// Eg:
|
||||
// Example:
|
||||
// Order("id desc")
|
||||
// Order("id", "desc").
|
||||
// Order("id", "desc")
|
||||
// Order("id desc,name asc")
|
||||
// Order("id desc", "name asc")
|
||||
// Order("id desc").Order("name asc")
|
||||
// Order(gdb.Raw("field(id, 3,1,2)")).
|
||||
func (m *Model) Order(orderBy ...interface{}) *Model {
|
||||
if len(orderBy) == 0 {
|
||||
return m
|
||||
}
|
||||
model := m.getModel()
|
||||
if model.orderBy != "" {
|
||||
model.orderBy += ","
|
||||
}
|
||||
var (
|
||||
core = m.db.GetCore()
|
||||
model = m.getModel()
|
||||
)
|
||||
for _, v := range orderBy {
|
||||
if model.orderBy != "" {
|
||||
model.orderBy += ","
|
||||
}
|
||||
switch v.(type) {
|
||||
case Raw, *Raw:
|
||||
model.orderBy += gconv.String(v)
|
||||
return model
|
||||
default:
|
||||
orderByStr := gconv.String(v)
|
||||
if gstr.Contains(orderByStr, " ") {
|
||||
model.orderBy += core.QuoteString(orderByStr)
|
||||
} else {
|
||||
if gstr.Equal(orderByStr, "ASC") || gstr.Equal(orderByStr, "DESC") {
|
||||
model.orderBy = gstr.TrimRight(model.orderBy, ",")
|
||||
model.orderBy += " " + orderByStr
|
||||
} else {
|
||||
model.orderBy += core.QuoteWord(orderByStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
model.orderBy += model.db.GetCore().QuoteString(gstr.JoinAny(orderBy, ", "))
|
||||
return model
|
||||
}
|
||||
|
||||
@ -68,10 +82,14 @@ func (m *Model) Group(groupBy ...string) *Model {
|
||||
if len(groupBy) == 0 {
|
||||
return m
|
||||
}
|
||||
model := m.getModel()
|
||||
var (
|
||||
core = m.db.GetCore()
|
||||
model = m.getModel()
|
||||
)
|
||||
|
||||
if model.groupBy != "" {
|
||||
model.groupBy += ","
|
||||
}
|
||||
model.groupBy += model.db.GetCore().QuoteString(strings.Join(groupBy, ","))
|
||||
model.groupBy += core.QuoteString(strings.Join(groupBy, ","))
|
||||
return model
|
||||
}
|
||||
|
||||
@ -283,10 +283,12 @@ func (m *Model) Scan(pointer interface{}, where ...interface{}) error {
|
||||
}
|
||||
}
|
||||
|
||||
// ScanAndCount scans a single record or record array that matches the given conditions and counts the total number of records that match those conditions.
|
||||
// If useFieldForCount is true, it will use the fields specified in the model for counting;
|
||||
// The pointer parameter is a pointer to a struct that the scanned data will be stored in.
|
||||
// The pointerCount parameter is a pointer to an integer that will be set to the total number of records that match the given conditions.
|
||||
// ScanAndCount scans a single record or record array that matches the given conditions and counts the total number
|
||||
// of records that match those conditions.
|
||||
//
|
||||
// If `useFieldForCount` is true, it will use the fields specified in the model for counting;
|
||||
// The `pointer` parameter is a pointer to a struct that the scanned data will be stored in.
|
||||
// The `totalCount` parameter is a pointer to an integer that will be set to the total number of records that match the given conditions.
|
||||
// The where parameter is an optional list of conditions to use when retrieving records.
|
||||
//
|
||||
// Example:
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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.1
|
||||
github.com/gogf/gf/contrib/config/consul/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/config/kubecm/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/config/nacos/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/config/polaris/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/metric/otelmetric/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/registry/etcd/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/registry/file/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/registry/nacos/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/registry/polaris/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/trace/otlpgrpc/v2 v2.8.1
|
||||
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.8.1
|
||||
github.com/gogf/gf/v2 v2.8.1
|
||||
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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -63,8 +63,14 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
validationRuleKeyForRequired = `required`
|
||||
validationRuleKeyForIn = `in:`
|
||||
validationRuleKeyForRequired = `required`
|
||||
validationRuleKeyForIn = `in:`
|
||||
validationRuleKeyForMax = `max:`
|
||||
validationRuleKeyForMin = `min:`
|
||||
validationRuleKeyForLength = `length:`
|
||||
validationRuleKeyForMaxLength = `max-length:`
|
||||
validationRuleKeyForMinLength = `min-length:`
|
||||
validationRuleKeyForBetween = `between:`
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@ -52,6 +52,17 @@ func (e *Examples) applyExamplesFile(path string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = e.applyExamplesData(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Examples) applyExamplesData(data interface{}) error {
|
||||
if empty.IsNil(e) || empty.IsNil(data) {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := data.(type) {
|
||||
case map[string]interface{}:
|
||||
|
||||
@ -255,12 +255,12 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
// =================================================================================================================
|
||||
// Other Responses.
|
||||
// =================================================================================================================
|
||||
if enhancedResponse, ok := outputObject.Interface().(ResponseStatusDef); ok {
|
||||
for statusCode, data := range enhancedResponse.ResponseStatusMap() {
|
||||
if enhancedResponse, ok := outputObject.Interface().(IEnhanceResponseStatus); ok {
|
||||
for statusCode, data := range enhancedResponse.EnhanceResponseStatus() {
|
||||
if statusCode < 100 || statusCode >= 600 {
|
||||
return gerror.Newf("Invalid HTTP status code: %d", statusCode)
|
||||
}
|
||||
if data == nil {
|
||||
if data.Response == nil {
|
||||
continue
|
||||
}
|
||||
status := gconv.String(statusCode)
|
||||
|
||||
@ -12,13 +12,22 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// StatusCode is http status for response.
|
||||
type StatusCode = int
|
||||
// EnhancedStatusCode is http status for response.
|
||||
type EnhancedStatusCode = int
|
||||
|
||||
// ResponseStatusDef is used to enhance the documentation of the response.
|
||||
// EnhancedStatusType is the structure for certain response status.
|
||||
// Currently, it only supports `Response` and `Examples`.
|
||||
// `Response` is the response structure
|
||||
// `Examples` is the examples for the response, map[string]interface{}, []interface{} are supported.
|
||||
type EnhancedStatusType struct {
|
||||
Response any
|
||||
Examples any
|
||||
}
|
||||
|
||||
// IEnhanceResponseStatus is used to enhance the documentation of the response.
|
||||
// Normal response structure could implement this interface to provide more information.
|
||||
type ResponseStatusDef interface {
|
||||
ResponseStatusMap() map[StatusCode]any
|
||||
type IEnhanceResponseStatus interface {
|
||||
EnhanceResponseStatus() map[EnhancedStatusCode]EnhancedStatusType
|
||||
}
|
||||
|
||||
// Response is specified by OpenAPI/Swagger 3.0 standard.
|
||||
|
||||
@ -26,7 +26,14 @@ type Responses map[string]ResponseRef
|
||||
|
||||
// object could be someObject.Interface()
|
||||
// There may be some difference between someObject.Type() and reflect.TypeOf(object).
|
||||
func (oai *OpenApiV3) getResponseFromObject(object interface{}, isDefault bool) (*Response, error) {
|
||||
func (oai *OpenApiV3) getResponseFromObject(data interface{}, isDefault bool) (*Response, error) {
|
||||
var object interface{}
|
||||
enhancedResponse, isEnhanced := data.(EnhancedStatusType)
|
||||
if isEnhanced {
|
||||
object = enhancedResponse.Response
|
||||
} else {
|
||||
object = data
|
||||
}
|
||||
// Add object schema to oai
|
||||
if err := oai.addSchema(object); err != nil {
|
||||
return nil, err
|
||||
@ -86,6 +93,14 @@ func (oai *OpenApiV3) getResponseFromObject(object interface{}, isDefault bool)
|
||||
}
|
||||
}
|
||||
|
||||
// Override examples from enhanced response.
|
||||
if isEnhanced {
|
||||
err := examples.applyExamplesData(enhancedResponse.Examples)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Generate response schema from input.
|
||||
schemaRef, err := oai.getResponseSchemaRef(refInput)
|
||||
if err != nil {
|
||||
|
||||
@ -8,6 +8,7 @@ package goai
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
@ -176,7 +177,7 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) {
|
||||
// struct.
|
||||
structFields, _ := gstructs.Fields(gstructs.FieldsInput{
|
||||
Pointer: object,
|
||||
RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag,
|
||||
RecursiveOption: gstructs.RecursiveOptionEmbedded,
|
||||
})
|
||||
schema.Type = TypeObject
|
||||
for _, structField := range structFields {
|
||||
@ -204,6 +205,56 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) {
|
||||
if validationRuleSet.Contains(validationRuleKeyForRequired) {
|
||||
schema.Required = append(schema.Required, key)
|
||||
}
|
||||
|
||||
// Extract validation rules to schema. like min, max, length
|
||||
lstRules := gstr.Split(ref.Value.ValidationRules, "|")
|
||||
for _, rule := range lstRules {
|
||||
if strings.HasPrefix(rule, validationRuleKeyForMax) {
|
||||
if ref.Value.Type == "integer" || ref.Value.Type == "number" {
|
||||
f := gconv.Float64(rule[4:])
|
||||
ref.Value.Max = &f
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rule, validationRuleKeyForMaxLength) {
|
||||
maxlength := gconv.Uint64(rule[11:])
|
||||
ref.Value.MaxLength = &maxlength
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rule, validationRuleKeyForMin) {
|
||||
if ref.Value.Type == "integer" || ref.Value.Type == "number" {
|
||||
f := gconv.Float64(rule[4:])
|
||||
ref.Value.Min = &f
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rule, validationRuleKeyForMinLength) {
|
||||
minlength := gconv.Uint64(rule[11:])
|
||||
ref.Value.MinLength = minlength
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rule, validationRuleKeyForLength) {
|
||||
lengthRule := gstr.Split(rule[7:], ",")
|
||||
if len(lengthRule) == 2 {
|
||||
minlength := gconv.Uint64(lengthRule[0])
|
||||
ref.Value.MinLength = minlength
|
||||
maxlength := gconv.Uint64(lengthRule[1])
|
||||
ref.Value.MaxLength = &maxlength
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rule, validationRuleKeyForBetween) {
|
||||
if ref.Value.Type == "integer" || ref.Value.Type == "number" {
|
||||
lengthRule := gstr.Split(rule[8:], ",")
|
||||
if len(lengthRule) == 2 {
|
||||
minimum := gconv.Float64(lengthRule[0])
|
||||
ref.Value.Min = &minimum
|
||||
maximum := gconv.Float64(lengthRule[1])
|
||||
ref.Value.Max = &maximum
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !isValidParameterName(key) {
|
||||
ignoreProperties = append(ignoreProperties, key)
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/net/goai"
|
||||
@ -119,71 +120,97 @@ func Test_Issue3135(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
type Issue3747CommonRes struct {
|
||||
type Issue3889CommonRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type Issue3747Req struct {
|
||||
type Issue3889Req struct {
|
||||
g.Meta `path:"/default" method:"post"`
|
||||
Name string
|
||||
}
|
||||
type Issue3747Res struct {
|
||||
g.Meta `status:"201" resEg:"testdata/Issue3747JsonFile/201.json"`
|
||||
type Issue3889Res struct {
|
||||
g.Meta `status:"201" resEg:"testdata/Issue3889JsonFile/201.json"`
|
||||
Info string `json:"info" eg:"Created!"`
|
||||
}
|
||||
|
||||
// Example case
|
||||
type Issue3747Res401 struct {
|
||||
g.Meta `resEg:"testdata/Issue3747JsonFile/401.json"`
|
||||
}
|
||||
type Issue3889Res401 struct{}
|
||||
|
||||
// Override case 1
|
||||
type Issue3747Res402 struct {
|
||||
type Issue3889Res402 struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// Override case 2
|
||||
type Issue3747Res403 struct {
|
||||
type Issue3889Res403 struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Common response case
|
||||
type Issue3747Res404 struct{}
|
||||
type Issue3889Res404 struct{}
|
||||
|
||||
func (r Issue3747Res) ResponseStatusMap() map[goai.StatusCode]any {
|
||||
return map[goai.StatusCode]any{
|
||||
401: Issue3747Res401{},
|
||||
402: Issue3747Res402{},
|
||||
403: Issue3747Res403{},
|
||||
404: Issue3747Res404{},
|
||||
405: struct{}{},
|
||||
407: interface{}(nil),
|
||||
406: nil,
|
||||
var Issue3889ErrorRes = map[int][]gcode.Code{
|
||||
401: {
|
||||
gcode.New(1, "Aha, 401 - 1", nil),
|
||||
gcode.New(2, "Aha, 401 - 2", nil),
|
||||
},
|
||||
}
|
||||
|
||||
func (r Issue3889Res) EnhanceResponseStatus() map[goai.EnhancedStatusCode]goai.EnhancedStatusType {
|
||||
Codes401 := Issue3889ErrorRes[401]
|
||||
// iterate Codes401 to generate Examples
|
||||
var Examples401 []interface{}
|
||||
for _, code := range Codes401 {
|
||||
example := Issue3889CommonRes{
|
||||
Code: code.Code(),
|
||||
Message: code.Message(),
|
||||
Data: nil,
|
||||
}
|
||||
Examples401 = append(Examples401, example)
|
||||
}
|
||||
return map[goai.EnhancedStatusCode]goai.EnhancedStatusType{
|
||||
401: {
|
||||
Response: Issue3889Res401{},
|
||||
Examples: Examples401,
|
||||
},
|
||||
402: {
|
||||
Response: Issue3889Res402{},
|
||||
},
|
||||
403: {
|
||||
Response: Issue3889Res403{},
|
||||
},
|
||||
404: {
|
||||
Response: Issue3889Res404{},
|
||||
},
|
||||
500: {
|
||||
Response: struct{}{},
|
||||
},
|
||||
501: {},
|
||||
}
|
||||
}
|
||||
|
||||
type Issue3747 struct{}
|
||||
type Issue3889 struct{}
|
||||
|
||||
func (Issue3747) Default(ctx context.Context, req *Issue3747Req) (res *Issue3747Res, err error) {
|
||||
res = &Issue3747Res{}
|
||||
func (Issue3889) Default(ctx context.Context, req *Issue3889Req) (res *Issue3889Res, err error) {
|
||||
res = &Issue3889Res{}
|
||||
return
|
||||
}
|
||||
|
||||
// https://github.com/gogf/gf/issues/3747
|
||||
func Test_Issue3747(t *testing.T) {
|
||||
// https://github.com/gogf/gf/issues/3889
|
||||
func Test_Issue3889(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := g.Server(guid.S())
|
||||
openapi := s.GetOpenApi()
|
||||
openapi.Config.CommonResponse = Issue3747CommonRes{}
|
||||
openapi.Config.CommonResponse = Issue3889CommonRes{}
|
||||
openapi.Config.CommonResponseDataField = `Data`
|
||||
s.Use(ghttp.MiddlewareHandlerResponse)
|
||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||
group.Bind(
|
||||
new(Issue3747),
|
||||
new(Issue3889),
|
||||
)
|
||||
})
|
||||
s.SetLogger(nil)
|
||||
@ -205,29 +232,71 @@ func Test_Issue3747(t *testing.T) {
|
||||
t.AssertNE(j.Get(`paths./default.post.responses.402`).String(), "")
|
||||
t.AssertNE(j.Get(`paths./default.post.responses.403`).String(), "")
|
||||
t.AssertNE(j.Get(`paths./default.post.responses.404`).String(), "")
|
||||
t.AssertNE(j.Get(`paths./default.post.responses.405`).String(), "")
|
||||
t.Assert(j.Get(`paths./default.post.responses.406`).String(), "")
|
||||
t.Assert(j.Get(`paths./default.post.responses.407`).String(), "")
|
||||
|
||||
t.AssertNE(j.Get(`paths./default.post.responses.500`).String(), "")
|
||||
t.Assert(j.Get(`paths./default.post.responses.501`).String(), "")
|
||||
// Check content
|
||||
commonResponseSchema := `{"properties":{"code":{"format":"int","type":"integer"},"data":{"properties":{},"type":"object"},"message":{"format":"string","type":"string"}},"type":"object"}`
|
||||
Status201ExamplesContent := `{"code 1":{"value":{"code":1,"data":"Good","message":"Aha, 201 - 1"}},"code 2":{"value":{"code":2,"data":"Not Bad","message":"Aha, 201 - 2"}}}`
|
||||
Status401ExamplesContent := `{"example 1":{"value":{"code":1,"data":null,"message":"Aha, 401 - 1"}},"example 2":{"value":{"code":2,"data":null,"message":"Aha, 401 - 2"}}}`
|
||||
Status402SchemaContent := `{"$ref":"#/components/schemas/github.com.gogf.gf.v2.net.goai_test.Issue3747Res402"}`
|
||||
Issue3747Res403Ref := `{"$ref":"#/components/schemas/github.com.gogf.gf.v2.net.goai_test.Issue3747Res403"}`
|
||||
Status402SchemaContent := `{"$ref":"#/components/schemas/github.com.gogf.gf.v2.net.goai_test.Issue3889Res402"}`
|
||||
Issue3889Res403Ref := `{"$ref":"#/components/schemas/github.com.gogf.gf.v2.net.goai_test.Issue3889Res403"}`
|
||||
|
||||
t.Assert(j.Get(`paths./default.post.responses.201.content.application/json.examples`).String(), Status201ExamplesContent)
|
||||
t.Assert(j.Get(`paths./default.post.responses.401.content.application/json.examples`).String(), Status401ExamplesContent)
|
||||
t.Assert(j.Get(`paths./default.post.responses.402.content.application/json.schema`).String(), Status402SchemaContent)
|
||||
t.Assert(j.Get(`paths./default.post.responses.403.content.application/json.schema`).String(), Issue3747Res403Ref)
|
||||
t.Assert(j.Get(`paths./default.post.responses.403.content.application/json.schema`).String(), Issue3889Res403Ref)
|
||||
t.Assert(j.Get(`paths./default.post.responses.404.content.application/json.schema`).String(), commonResponseSchema)
|
||||
t.Assert(j.Get(`paths./default.post.responses.405.content.application/json.schema`).String(), commonResponseSchema)
|
||||
t.Assert(j.Get(`paths./default.post.responses.500.content.application/json.schema`).String(), commonResponseSchema)
|
||||
|
||||
api := s.GetOpenApi()
|
||||
reqPath := "github.com.gogf.gf.v2.net.goai_test.Issue3747Res403"
|
||||
reqPath := "github.com.gogf.gf.v2.net.goai_test.Issue3889Res403"
|
||||
schema := api.Components.Schemas.Get(reqPath).Value
|
||||
|
||||
Issue3747Res403Schema := `{"properties":{"code":{"format":"int","type":"integer"},"message":{"format":"string","type":"string"}},"type":"object"}`
|
||||
t.Assert(schema, Issue3747Res403Schema)
|
||||
Issue3889Res403Schema := `{"properties":{"code":{"format":"int","type":"integer"},"message":{"format":"string","type":"string"}},"type":"object"}`
|
||||
t.Assert(schema, Issue3889Res403Schema)
|
||||
})
|
||||
}
|
||||
|
||||
type Issue3930DefaultReq struct {
|
||||
g.Meta `path:"/user/{id}" method:"get" tags:"User" summary:"Get one user"`
|
||||
Id int64 `v:"required" dc:"user id"`
|
||||
}
|
||||
type Issue3930DefaultRes struct {
|
||||
*Issue3930User `dc:"user"`
|
||||
}
|
||||
type Issue3930User struct {
|
||||
Id uint `json:"id" orm:"id" description:"user id"` // user id
|
||||
}
|
||||
|
||||
type Issue3930 struct{}
|
||||
|
||||
func (Issue3930) Default(ctx context.Context, req *Issue3930DefaultReq) (res *Issue3930DefaultRes, err error) {
|
||||
res = &Issue3930DefaultRes{}
|
||||
return
|
||||
}
|
||||
|
||||
// https://github.com/gogf/gf/issues/3930
|
||||
func Test_Issue3930(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := g.Server(guid.S())
|
||||
s.Use(ghttp.MiddlewareHandlerResponse)
|
||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||
group.Bind(
|
||||
new(Issue3930),
|
||||
)
|
||||
})
|
||||
s.SetLogger(nil)
|
||||
s.SetOpenApiPath("/api.json")
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
var (
|
||||
api = s.GetOpenApi()
|
||||
reqPath = "github.com.gogf.gf.v2.net.goai_test.Issue3930DefaultRes"
|
||||
)
|
||||
t.AssertNE(api.Components.Schemas.Get(reqPath).Value.Properties.Get("id"), nil)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1200,8 +1200,8 @@ func TestOpenApiV3_PathSecurity(t *testing.T) {
|
||||
|
||||
type Req struct {
|
||||
gmeta.Meta `method:"PUT" security:"apiKey"` // 这里的apiKey要和openApi定义的key一致
|
||||
Product string `json:"product" v:"required" description:"Unique product key"`
|
||||
Name string `json:"name" v:"required" description:"Instance name"`
|
||||
Product string `json:"product" v:"required" description:"Unique product key"`
|
||||
Name string `json:"name" v:"required" description:"Instance name"`
|
||||
}
|
||||
type Res struct{}
|
||||
|
||||
@ -1345,3 +1345,35 @@ func Test_XExtension(t *testing.T) {
|
||||
t.Assert(oai.String(), gtest.DataContent("XExtension", "expect.json"))
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ValidationRules(t *testing.T) {
|
||||
type Req struct {
|
||||
g.Meta `path:"/rules" method:"POST" tags:"Rules" summary:"Validation rules."`
|
||||
Name string `v:"required|min-length:3|max-length:32#required|min|max" dc:"Name"`
|
||||
Age int `v:"required|min:1|max:100" dc:"Age"`
|
||||
Grade int `v:"between:1,12#please enter the correct grade." dc:"Grade"`
|
||||
Address string `v:"length:3,64" dc:"Address"`
|
||||
}
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
err error
|
||||
oai = goai.New()
|
||||
req = new(Req)
|
||||
)
|
||||
err = oai.Add(goai.AddInput{
|
||||
Object: req,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
schema := oai.Components.Schemas.Get("github.com.gogf.gf.v2.net.goai_test.Req").Value
|
||||
t.Assert(schema.Properties.Get("Name").Value.MinLength, 3)
|
||||
t.Assert(schema.Properties.Get("Name").Value.MaxLength, 32)
|
||||
t.Assert(schema.Properties.Get("Age").Value.Min, 1.0)
|
||||
t.Assert(schema.Properties.Get("Age").Value.Max, 100.0)
|
||||
t.Assert(schema.Properties.Get("Grade").Value.Min, 1.0)
|
||||
t.Assert(schema.Properties.Get("Grade").Value.Max, 12.0)
|
||||
t.Assert(schema.Properties.Get("Address").Value.MinLength, 3)
|
||||
t.Assert(schema.Properties.Get("Address").Value.MaxLength, 64)
|
||||
})
|
||||
}
|
||||
|
||||
12
net/goai/testdata/Issue3747JsonFile/401.json
vendored
12
net/goai/testdata/Issue3747JsonFile/401.json
vendored
@ -1,12 +0,0 @@
|
||||
[
|
||||
{
|
||||
"code": 1,
|
||||
"message": "Aha, 401 - 1",
|
||||
"data": null
|
||||
},
|
||||
{
|
||||
"code": 2,
|
||||
"message": "Aha, 401 - 2",
|
||||
"data": null
|
||||
}
|
||||
]
|
||||
@ -288,11 +288,7 @@ func (c *AdapterMemory) GetExpire(ctx context.Context, key interface{}) (time.Du
|
||||
// If multiple keys are given, it returns the value of the last deleted item.
|
||||
func (c *AdapterMemory) Remove(ctx context.Context, keys ...interface{}) (*gvar.Var, error) {
|
||||
defer c.lru.Remove(keys...)
|
||||
value, err := c.doRemove(ctx, keys...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gvar.New(value), nil
|
||||
return c.doRemove(ctx, keys...)
|
||||
}
|
||||
|
||||
func (c *AdapterMemory) doRemove(_ context.Context, keys ...interface{}) (*gvar.Var, error) {
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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`)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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},
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -2,5 +2,5 @@ package gf
|
||||
|
||||
const (
|
||||
// VERSION is the current GoFrame version.
|
||||
VERSION = "v2.8.0-beta"
|
||||
VERSION = "v2.8.1"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user