优化方法的使用
This commit is contained in:
Executable
+24
@@ -0,0 +1,24 @@
|
||||
module code.yun.ink/pkg/responsex/gormx
|
||||
|
||||
go 1.22.4
|
||||
|
||||
require (
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
gorm.io/gorm v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
modernc.org/libc v1.22.5 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/sqlite v1.23.1 // indirect
|
||||
)
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
|
||||
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
|
||||
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
Regular → Executable
+6
@@ -1,8 +1,14 @@
|
||||
// Package gormx 提供 responsex 的 GORM 分页辅助。
|
||||
//
|
||||
// 按需加载:只有显式 import 本包的项目才依赖 gorm。
|
||||
//
|
||||
// import 路径:code.yun.ink/pkg/responsex/gormx
|
||||
package gormx
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
// 计算GORM DB的分页
|
||||
// page 与 size 同时小于等于 0 时,只限制最大条数(1000),不做偏移
|
||||
func GetDbOffset(db *gorm.DB, page, size int64) *gorm.DB {
|
||||
offset := int(0)
|
||||
limit := int(0)
|
||||
|
||||
Regular → Executable
+38
-10
@@ -1,6 +1,8 @@
|
||||
package gormx_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.yun.ink/pkg/responsex/gormx"
|
||||
@@ -18,19 +20,29 @@ func newDB(t *testing.T) *gorm.DB {
|
||||
return db
|
||||
}
|
||||
|
||||
// newDryRunDB 创建 DryRun 模式的 DB,用于断言生成的 SQL,不真正查询
|
||||
func newDryRunDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{DryRun: true})
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite failed: %v", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func TestGetDbOffset(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
page, size int64
|
||||
wantOffset int
|
||||
wantLimit int
|
||||
name string
|
||||
page, size int64
|
||||
wantOffset int
|
||||
wantLimit int
|
||||
}{
|
||||
{"page1 size10", 1, 10, 0, 10},
|
||||
{"page2 size10", 2, 10, 10, 10},
|
||||
{"page3 size20", 3, 20, 40, 20},
|
||||
{"page0 size10 default page to 1", 0, 10, 0, 10},
|
||||
{"page1 size0 default size to 10", 1, 0, 0, 10},
|
||||
{"both negative or zero max 1000", 0, 0, 0, 1000},
|
||||
{"both zero max 1000", 0, 0, 0, 1000},
|
||||
{"negative page default to 1", -1, 10, 0, 10},
|
||||
{"negative size default to 10", 1, -1, 0, 10},
|
||||
{"both negative", -1, -1, 0, 1000},
|
||||
@@ -39,14 +51,28 @@ func TestGetDbOffset(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
db := newDB(t)
|
||||
result := gormx.GetDbOffset(db, tt.page, tt.size)
|
||||
db := newDryRunDB(t)
|
||||
var m testModel
|
||||
stmt := gormx.GetDbOffset(db, tt.page, tt.size).Find(&m).Statement
|
||||
|
||||
stmt := result.Statement
|
||||
// 验证 Limit 被正确设置
|
||||
if stmt == nil {
|
||||
t.Fatal("statement is nil")
|
||||
}
|
||||
got := stmt.SQL.String()
|
||||
if got == "" {
|
||||
t.Fatal("no SQL generated")
|
||||
}
|
||||
// 断言生成的 SQL 片段,避免依赖 Vars 顺序
|
||||
wantLimit := fmt.Sprintf("LIMIT %d", tt.wantLimit)
|
||||
if tt.wantOffset > 0 {
|
||||
wantOffset := fmt.Sprintf("OFFSET %d", tt.wantOffset)
|
||||
if !strings.Contains(got, wantOffset) {
|
||||
t.Errorf("sql %q 缺少 %q", got, wantOffset)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(got, wantLimit) {
|
||||
t.Errorf("sql %q 缺少 %q", got, wantLimit)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -54,7 +80,9 @@ func TestGetDbOffset(t *testing.T) {
|
||||
func TestGetDbOffset_Chaining(t *testing.T) {
|
||||
db := newDB(t)
|
||||
|
||||
db.AutoMigrate(&testModel{})
|
||||
if err := db.AutoMigrate(&testModel{}); err != nil {
|
||||
t.Fatalf("migrate failed: %v", err)
|
||||
}
|
||||
|
||||
// 插入测试数据
|
||||
for i := 1; i <= 50; i++ {
|
||||
|
||||
Reference in New Issue
Block a user