hasone hasmany 改
This commit is contained in:
parent
044e55a399
commit
6caf07b575
|
@ -94,7 +94,7 @@ func GetPostsByIds(a ...any) (m map[uint64]models.Posts, err error) {
|
||||||
|
|
||||||
func SearchPostIds(args ...any) (ids PostIds, err error) {
|
func SearchPostIds(args ...any) (ids PostIds, err error) {
|
||||||
ctx := args[0].(context.Context)
|
ctx := args[0].(context.Context)
|
||||||
q := args[1].(model.QueryCondition)
|
q := args[1].(*model.QueryCondition)
|
||||||
page := args[2].(int)
|
page := args[2].(int)
|
||||||
pageSize := args[3].(int)
|
pageSize := args[3].(int)
|
||||||
q.Fields = "ID"
|
q.Fields = "ID"
|
||||||
|
|
|
@ -79,7 +79,7 @@ func (i *IndexHandle) ParseIndex(parm *IndexParams) (err error) {
|
||||||
|
|
||||||
func (i *IndexHandle) GetIndexData() (posts []models.Posts, totalRaw int, err error) {
|
func (i *IndexHandle) GetIndexData() (posts []models.Posts, totalRaw int, err error) {
|
||||||
|
|
||||||
q := model.QueryCondition{
|
q := &model.QueryCondition{
|
||||||
Where: i.Param.Where,
|
Where: i.Param.Where,
|
||||||
Order: model.SqlBuilder{{i.Param.OrderBy, i.Param.Order}},
|
Order: model.SqlBuilder{{i.Param.OrderBy, i.Param.Order}},
|
||||||
Join: i.Param.Join,
|
Join: i.Param.Join,
|
||||||
|
|
|
@ -12,28 +12,19 @@ type QueryCondition struct {
|
||||||
Offset int
|
Offset int
|
||||||
In [][]any
|
In [][]any
|
||||||
Relation map[string]*QueryCondition
|
Relation map[string]*QueryCondition
|
||||||
|
WithJoin bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func Conditions(fns ...Condition) QueryCondition {
|
func Conditions(fns ...Condition) *QueryCondition {
|
||||||
r := QueryCondition{}
|
r := &QueryCondition{}
|
||||||
for _, fn := range fns {
|
for _, fn := range fns {
|
||||||
fn(&r)
|
fn(r)
|
||||||
}
|
}
|
||||||
if r.Fields == "" {
|
if r.Fields == "" {
|
||||||
r.Fields = "*"
|
r.Fields = "*"
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
func WithConditions(fns ...Condition) *QueryCondition {
|
|
||||||
r := QueryCondition{}
|
|
||||||
for _, fn := range fns {
|
|
||||||
fn(&r)
|
|
||||||
}
|
|
||||||
if r.Fields == "" {
|
|
||||||
r.Fields = "*"
|
|
||||||
}
|
|
||||||
return &r
|
|
||||||
}
|
|
||||||
|
|
||||||
type Condition func(c *QueryCondition)
|
type Condition func(c *QueryCondition)
|
||||||
|
|
||||||
|
@ -104,3 +95,9 @@ func With(tableTag string, q *QueryCondition) Condition {
|
||||||
c.Relation[tableTag] = q
|
c.Relation[tableTag] = q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithJoin(isJoin bool) Condition {
|
||||||
|
return func(c *QueryCondition) {
|
||||||
|
c.WithJoin = isJoin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ func (c count[T]) Table() string {
|
||||||
return c.t.Table()
|
return c.t.Table()
|
||||||
}
|
}
|
||||||
|
|
||||||
func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) (r []T, total int, err error) {
|
func pagination[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) (r []T, total int, err error) {
|
||||||
if page < 1 || pageSize < 1 {
|
if page < 1 || pageSize < 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition, page
|
||||||
if qx.From == "" {
|
if qx.From == "" {
|
||||||
qx.From = Table[T]()
|
qx.From = Table[T]()
|
||||||
}
|
}
|
||||||
sq, in, er := BuildQuerySql(qx)
|
sq, in, er := BuildQuerySql(&qx)
|
||||||
qx.In = [][]any{in}
|
qx.In = [][]any{in}
|
||||||
if er != nil {
|
if er != nil {
|
||||||
err = er
|
err = er
|
||||||
|
@ -55,7 +55,7 @@ func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition, page
|
||||||
Fields: "count(*) n",
|
Fields: "count(*) n",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n, err := gets[count[T]](db, ctx, qx)
|
n, err := gets[count[T]](db, ctx, &qx)
|
||||||
total = n.N
|
total = n.N
|
||||||
if err != nil || total < 1 {
|
if err != nil || total < 1 {
|
||||||
return
|
return
|
||||||
|
@ -77,21 +77,21 @@ func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition, page
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func paginationToMap[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
func paginationToMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
||||||
ctx = context.WithValue(ctx, "handle=>toMap", &r)
|
ctx = context.WithValue(ctx, "handle=>toMap", &r)
|
||||||
_, total, err = pagination[T](db, ctx, q, page, pageSize)
|
_, total, err = pagination[T](db, ctx, q, page, pageSize)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func PaginationToMap[T Model](ctx context.Context, q QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
func PaginationToMap[T Model](ctx context.Context, q *QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
||||||
return paginationToMap[T](globalBb, ctx, q, page, pageSize)
|
return paginationToMap[T](globalBb, ctx, q, page, pageSize)
|
||||||
}
|
}
|
||||||
func PaginationToMapFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
func PaginationToMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
||||||
return paginationToMap[T](db, ctx, q, page, pageSize)
|
return paginationToMap[T](db, ctx, q, page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindOneById[T Model, I constraints.Integer](ctx context.Context, id I) (T, error) {
|
func FindOneById[T Model, I constraints.Integer](ctx context.Context, id I) (T, error) {
|
||||||
return gets[T](globalBb, ctx, QueryCondition{
|
return gets[T](globalBb, ctx, &QueryCondition{
|
||||||
Fields: "*",
|
Fields: "*",
|
||||||
Where: SqlBuilder{
|
Where: SqlBuilder{
|
||||||
{PrimaryKey[T](), "=", number.IntToString(id), "int"},
|
{PrimaryKey[T](), "=", number.IntToString(id), "int"},
|
||||||
|
@ -119,7 +119,7 @@ func LastOne[T Model](ctx context.Context, where ParseWhere, fields string, in .
|
||||||
}
|
}
|
||||||
|
|
||||||
func SimpleFind[T Model](ctx context.Context, where ParseWhere, fields string, in ...[]any) (r []T, err error) {
|
func SimpleFind[T Model](ctx context.Context, where ParseWhere, fields string, in ...[]any) (r []T, err error) {
|
||||||
s, args, err := BuildQuerySql(QueryCondition{
|
s, args, err := BuildQuerySql(&QueryCondition{
|
||||||
Where: where,
|
Where: where,
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
In: in,
|
In: in,
|
||||||
|
@ -144,7 +144,7 @@ func Select[T Model](ctx context.Context, sql string, params ...any) ([]T, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func Find[T Model](ctx context.Context, where ParseWhere, fields, group string, order SqlBuilder, join SqlBuilder, having SqlBuilder, limit int, in ...[]any) (r []T, err error) {
|
func Find[T Model](ctx context.Context, where ParseWhere, fields, group string, order SqlBuilder, join SqlBuilder, having SqlBuilder, limit int, in ...[]any) (r []T, err error) {
|
||||||
q := QueryCondition{
|
q := &QueryCondition{
|
||||||
Where: where,
|
Where: where,
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
Group: group,
|
Group: group,
|
||||||
|
|
|
@ -41,6 +41,12 @@ type post struct {
|
||||||
PostMeta *[]models.PostMeta `table:"wp_postmeta meta" foreignKey:"post_id" local:"ID" relation:"hasMany"`
|
PostMeta *[]models.PostMeta `table:"wp_postmeta meta" foreignKey:"post_id" local:"ID" relation:"hasMany"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TermRelationships struct {
|
||||||
|
ObjectID uint64 `db:"object_id"`
|
||||||
|
TermTaxonomyId uint64 `db:"term_taxonomy_id"`
|
||||||
|
TermOrder int64 `db:"term_order"`
|
||||||
|
}
|
||||||
|
|
||||||
type user struct {
|
type user struct {
|
||||||
Id uint64 `gorm:"column:ID" db:"ID" json:"ID"`
|
Id uint64 `gorm:"column:ID" db:"ID" json:"ID"`
|
||||||
UserLogin string `gorm:"column:user_login" db:"user_login" json:"user_login"`
|
UserLogin string `gorm:"column:user_login" db:"user_login" json:"user_login"`
|
||||||
|
@ -329,6 +335,30 @@ func TestFindOneById(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGets2(t *testing.T) {
|
||||||
|
t.Run("hasOne", func(t *testing.T) {
|
||||||
|
{
|
||||||
|
q := Conditions(
|
||||||
|
Where(SqlBuilder{{"id = 190"}}),
|
||||||
|
With("user", Conditions(
|
||||||
|
Fields("ID,user_login,user_pass"),
|
||||||
|
)),
|
||||||
|
Fields("posts.*"),
|
||||||
|
From("wp_posts posts"),
|
||||||
|
With("meta", Conditions(
|
||||||
|
WithJoin(true),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
ctx = context.WithValue(ctx, "ancestorsQueryCondition", q)
|
||||||
|
got, err := Gets[post](ctx, q)
|
||||||
|
_ = got
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("err:%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestFirstOne(t *testing.T) {
|
func TestFirstOne(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
where ParseWhere
|
where ParseWhere
|
||||||
|
@ -365,18 +395,6 @@ func TestFirstOne(t *testing.T) {
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got, err := FirstOne[post](ctx, tt.args.where, tt.args.fields, tt.args.order, tt.args.in...)
|
got, err := FirstOne[post](ctx, tt.args.where, tt.args.fields, tt.args.order, tt.args.in...)
|
||||||
gott, err := Gets[post](ctx, Conditions(
|
|
||||||
Where(SqlBuilder{{"post_status", "publish"}}),
|
|
||||||
Order([][]string{{"ID", "desc"}}),
|
|
||||||
With("user", WithConditions(
|
|
||||||
Fields("ID,user_login,user_pass"),
|
|
||||||
Where(SqlBuilder{
|
|
||||||
{"user.ID", ">", "0", "int"},
|
|
||||||
}),
|
|
||||||
)),
|
|
||||||
With("meta", nil),
|
|
||||||
))
|
|
||||||
_ = gott
|
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("FirstOne() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("FirstOne() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
|
@ -483,7 +501,7 @@ func Test_pagination(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
page int
|
page int
|
||||||
pageSize int
|
pageSize int
|
||||||
}
|
}
|
||||||
|
@ -500,7 +518,7 @@ func Test_pagination(t *testing.T) {
|
||||||
args: args{
|
args: args{
|
||||||
db: glob,
|
db: glob,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
q: QueryCondition{
|
q: &QueryCondition{
|
||||||
Fields: "post_type,count(*) ID",
|
Fields: "post_type,count(*) ID",
|
||||||
Group: "post_type",
|
Group: "post_type",
|
||||||
Having: SqlBuilder{{"ID", ">", "1", "int"}},
|
Having: SqlBuilder{{"ID", ">", "1", "int"}},
|
||||||
|
@ -541,7 +559,7 @@ func Test_paginationToMap(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
page int
|
page int
|
||||||
pageSize int
|
pageSize int
|
||||||
}
|
}
|
||||||
|
@ -557,7 +575,7 @@ func Test_paginationToMap(t *testing.T) {
|
||||||
args: args{
|
args: args{
|
||||||
db: glob,
|
db: glob,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
q: QueryCondition{
|
q: &QueryCondition{
|
||||||
Fields: "ID",
|
Fields: "ID",
|
||||||
Where: SqlBuilder{{"ID < 200"}},
|
Where: SqlBuilder{{"ID < 200"}},
|
||||||
},
|
},
|
||||||
|
@ -572,7 +590,7 @@ func Test_paginationToMap(t *testing.T) {
|
||||||
args: args{
|
args: args{
|
||||||
db: glob,
|
db: glob,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
q: QueryCondition{
|
q: &QueryCondition{
|
||||||
Fields: "ID",
|
Fields: "ID",
|
||||||
Where: SqlBuilder{{"ID < 200"}},
|
Where: SqlBuilder{{"ID < 200"}},
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
// Finds 比 Find 多一个offset
|
// Finds 比 Find 多一个offset
|
||||||
//
|
//
|
||||||
// Conditions 中可用 Where Fields Group Having Join Order Offset Limit In 函数
|
// Conditions 中可用 Where Fields Group Having Join Order Offset Limit In 函数
|
||||||
func Finds[T Model](ctx context.Context, q QueryCondition) (r []T, err error) {
|
func Finds[T Model](ctx context.Context, q *QueryCondition) (r []T, err error) {
|
||||||
r, err = finds[T](globalBb, ctx, q)
|
r, err = finds[T](globalBb, ctx, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,13 @@ func Finds[T Model](ctx context.Context, q QueryCondition) (r []T, err error) {
|
||||||
// FindFromDB 同 Finds 使用指定 db 查询
|
// FindFromDB 同 Finds 使用指定 db 查询
|
||||||
//
|
//
|
||||||
// Conditions 中可用 Where Fields Group Having Join Order Offset Limit In 函数
|
// Conditions 中可用 Where Fields Group Having Join Order Offset Limit In 函数
|
||||||
func FindFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []T, err error) {
|
func FindFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []T, err error) {
|
||||||
r, err = finds[T](db, ctx, q)
|
r, err = finds[T](db, ctx, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func finds[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []T, err error) {
|
func finds[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []T, err error) {
|
||||||
setTable[T](&q)
|
setTable[T](q)
|
||||||
sq, args, err := BuildQuerySql(q)
|
sq, args, err := BuildQuerySql(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -36,7 +36,7 @@ func finds[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []T, e
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func chunkFind[T Model](db dbQuery, ctx context.Context, perLimit int, q QueryCondition) (r []T, err error) {
|
func chunkFind[T Model](db dbQuery, ctx context.Context, perLimit int, q *QueryCondition) (r []T, err error) {
|
||||||
i := 1
|
i := 1
|
||||||
var rr []T
|
var rr []T
|
||||||
var total int
|
var total int
|
||||||
|
@ -65,7 +65,7 @@ func chunkFind[T Model](db dbQuery, ctx context.Context, perLimit int, q QueryCo
|
||||||
// ChunkFind 分片查询并直接返回所有结果
|
// ChunkFind 分片查询并直接返回所有结果
|
||||||
//
|
//
|
||||||
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
||||||
func ChunkFind[T Model](ctx context.Context, perLimit int, q QueryCondition) (r []T, err error) {
|
func ChunkFind[T Model](ctx context.Context, perLimit int, q *QueryCondition) (r []T, err error) {
|
||||||
r, err = chunkFind[T](globalBb, ctx, perLimit, q)
|
r, err = chunkFind[T](globalBb, ctx, perLimit, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ func ChunkFind[T Model](ctx context.Context, perLimit int, q QueryCondition) (r
|
||||||
// ChunkFindFromDB 同 ChunkFind
|
// ChunkFindFromDB 同 ChunkFind
|
||||||
//
|
//
|
||||||
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
||||||
func ChunkFindFromDB[T Model](db dbQuery, ctx context.Context, perLimit int, q QueryCondition) (r []T, err error) {
|
func ChunkFindFromDB[T Model](db dbQuery, ctx context.Context, perLimit int, q *QueryCondition) (r []T, err error) {
|
||||||
r, err = chunkFind[T](db, ctx, perLimit, q)
|
r, err = chunkFind[T](db, ctx, perLimit, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func ChunkFindFromDB[T Model](db dbQuery, ctx context.Context, perLimit int, q Q
|
||||||
// Chunk 分片查询并函数过虑返回新类型的切片
|
// Chunk 分片查询并函数过虑返回新类型的切片
|
||||||
//
|
//
|
||||||
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
||||||
func Chunk[T Model, R any](ctx context.Context, perLimit int, fn func(rows T) (R, bool), q QueryCondition) (r []R, err error) {
|
func Chunk[T Model, R any](ctx context.Context, perLimit int, fn func(rows T) (R, bool), q *QueryCondition) (r []R, err error) {
|
||||||
r, err = chunk(globalBb, ctx, perLimit, fn, q)
|
r, err = chunk(globalBb, ctx, perLimit, fn, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -89,12 +89,12 @@ func Chunk[T Model, R any](ctx context.Context, perLimit int, fn func(rows T) (R
|
||||||
// ChunkFromDB 同 Chunk
|
// ChunkFromDB 同 Chunk
|
||||||
//
|
//
|
||||||
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
// Conditions 中可用 Where Fields Group Having Join Order Limit In 函数
|
||||||
func ChunkFromDB[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn func(rows T) (R, bool), q QueryCondition) (r []R, err error) {
|
func ChunkFromDB[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn func(rows T) (R, bool), q *QueryCondition) (r []R, err error) {
|
||||||
r, err = chunk(db, ctx, perLimit, fn, q)
|
r, err = chunk(db, ctx, perLimit, fn, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func chunk[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn func(rows T) (R, bool), q QueryCondition) (r []R, err error) {
|
func chunk[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn func(rows T) (R, bool), q *QueryCondition) (r []R, err error) {
|
||||||
i := 1
|
i := 1
|
||||||
var rr []T
|
var rr []T
|
||||||
var count int
|
var count int
|
||||||
|
@ -130,25 +130,25 @@ func chunk[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn fun
|
||||||
// Pagination 同
|
// Pagination 同
|
||||||
//
|
//
|
||||||
// Condition 中可使用 Where Fields From Group Having Join Order Limit In 函数
|
// Condition 中可使用 Where Fields From Group Having Join Order Limit In 函数
|
||||||
func Pagination[T Model](ctx context.Context, q QueryCondition, page, pageSize int) ([]T, int, error) {
|
func Pagination[T Model](ctx context.Context, q *QueryCondition, page, pageSize int) ([]T, int, error) {
|
||||||
return pagination[T](globalBb, ctx, q, page, pageSize)
|
return pagination[T](globalBb, ctx, q, page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaginationFromDB 同 Pagination 方便多个db使用
|
// PaginationFromDB 同 Pagination 方便多个db使用
|
||||||
//
|
//
|
||||||
// Condition 中可使用 Where Fields Group Having Join Order Limit In 函数
|
// Condition 中可使用 Where Fields Group Having Join Order Limit In 函数
|
||||||
func PaginationFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) ([]T, int, error) {
|
func PaginationFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) ([]T, int, error) {
|
||||||
return pagination[T](db, ctx, q, page, pageSize)
|
return pagination[T](db, ctx, q, page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Column[V Model, T any](ctx context.Context, fn func(V) (T, bool), q QueryCondition) ([]T, error) {
|
func Column[V Model, T any](ctx context.Context, fn func(V) (T, bool), q *QueryCondition) ([]T, error) {
|
||||||
return column[V, T](globalBb, ctx, fn, q)
|
return column[V, T](globalBb, ctx, fn, q)
|
||||||
}
|
}
|
||||||
func ColumnFromDB[V Model, T any](db dbQuery, ctx context.Context, fn func(V) (T, bool), q QueryCondition) (r []T, err error) {
|
func ColumnFromDB[V Model, T any](db dbQuery, ctx context.Context, fn func(V) (T, bool), q *QueryCondition) (r []T, err error) {
|
||||||
return column[V, T](db, ctx, fn, q)
|
return column[V, T](db, ctx, fn, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func column[V Model, T any](db dbQuery, ctx context.Context, fn func(V) (T, bool), q QueryCondition) (r []T, err error) {
|
func column[V Model, T any](db dbQuery, ctx context.Context, fn func(V) (T, bool), q *QueryCondition) (r []T, err error) {
|
||||||
res, err := finds[V](db, ctx, q)
|
res, err := finds[V](db, ctx, q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -157,11 +157,11 @@ func column[V Model, T any](db dbQuery, ctx context.Context, fn func(V) (T, bool
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetField[T Model](ctx context.Context, field string, q QueryCondition) (r string, err error) {
|
func GetField[T Model](ctx context.Context, field string, q *QueryCondition) (r string, err error) {
|
||||||
r, err = getField[T](globalBb, ctx, field, q)
|
r, err = getField[T](globalBb, ctx, field, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func getField[T Model](db dbQuery, ctx context.Context, field string, q QueryCondition) (r string, err error) {
|
func getField[T Model](db dbQuery, ctx context.Context, field string, q *QueryCondition) (r string, err error) {
|
||||||
if q.Fields == "" || q.Fields == "*" {
|
if q.Fields == "" || q.Fields == "*" {
|
||||||
q.Fields = field
|
q.Fields = field
|
||||||
}
|
}
|
||||||
|
@ -176,12 +176,12 @@ func getField[T Model](db dbQuery, ctx context.Context, field string, q QueryCon
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func GetFieldFromDB[T Model](db dbQuery, ctx context.Context, field string, q QueryCondition) (r string, err error) {
|
func GetFieldFromDB[T Model](db dbQuery, ctx context.Context, field string, q *QueryCondition) (r string, err error) {
|
||||||
return getField[T](db, ctx, field, q)
|
return getField[T](db, ctx, field, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getToStringMap[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r map[string]string, err error) {
|
func getToStringMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r map[string]string, err error) {
|
||||||
setTable[T](&q)
|
setTable[T](q)
|
||||||
rawSql, in, err := BuildQuerySql(q)
|
rawSql, in, err := BuildQuerySql(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -190,13 +190,13 @@ func getToStringMap[T Model](db dbQuery, ctx context.Context, q QueryCondition)
|
||||||
err = db.Get(ctx, &r, rawSql, in...)
|
err = db.Get(ctx, &r, rawSql, in...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func GetToStringMap[T Model](ctx context.Context, q QueryCondition) (r map[string]string, err error) {
|
func GetToStringMap[T Model](ctx context.Context, q *QueryCondition) (r map[string]string, err error) {
|
||||||
r, err = getToStringMap[T](globalBb, ctx, q)
|
r, err = getToStringMap[T](globalBb, ctx, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func findToStringMap[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []map[string]string, err error) {
|
func findToStringMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []map[string]string, err error) {
|
||||||
setTable[T](&q)
|
setTable[T](q)
|
||||||
rawSql, in, err := BuildQuerySql(q)
|
rawSql, in, err := BuildQuerySql(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -206,30 +206,30 @@ func findToStringMap[T Model](db dbQuery, ctx context.Context, q QueryCondition)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindToStringMap[T Model](ctx context.Context, q QueryCondition) (r []map[string]string, err error) {
|
func FindToStringMap[T Model](ctx context.Context, q *QueryCondition) (r []map[string]string, err error) {
|
||||||
r, err = findToStringMap[T](globalBb, ctx, q)
|
r, err = findToStringMap[T](globalBb, ctx, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindToStringMapFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []map[string]string, err error) {
|
func FindToStringMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []map[string]string, err error) {
|
||||||
r, err = findToStringMap[T](db, ctx, q)
|
r, err = findToStringMap[T](db, ctx, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetToStringMapFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r map[string]string, err error) {
|
func GetToStringMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r map[string]string, err error) {
|
||||||
r, err = getToStringMap[T](db, ctx, q)
|
r, err = getToStringMap[T](db, ctx, q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildQuerySql(q QueryCondition) (r string, args []any, err error) {
|
func BuildQuerySql(q *QueryCondition) (r string, args []any, err error) {
|
||||||
w := ""
|
where := ""
|
||||||
if q.Where != nil {
|
if q.Where != nil {
|
||||||
w, args, err = q.Where.ParseWhere(&q.In)
|
where, args, err = q.Where.ParseWhere(&q.In)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h := ""
|
having := ""
|
||||||
if q.Having != nil {
|
if q.Having != nil {
|
||||||
hh, arg, er := q.Having.ParseWhere(&q.In)
|
hh, arg, er := q.Having.ParseWhere(&q.In)
|
||||||
if er != nil {
|
if er != nil {
|
||||||
|
@ -237,15 +237,17 @@ func BuildQuerySql(q QueryCondition) (r string, args []any, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
args = append(args, arg...)
|
args = append(args, arg...)
|
||||||
h = strings.Replace(hh, " where", " having", 1)
|
having = strings.Replace(hh, " where", " having", 1)
|
||||||
}
|
}
|
||||||
if len(args) == 0 && len(q.In) > 0 {
|
if len(args) == 0 && len(q.In) > 0 {
|
||||||
for _, antes := range q.In {
|
for _, antes := range q.In {
|
||||||
args = append(args, antes...)
|
args = append(args, antes...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
join := ""
|
||||||
j := q.Join.parseJoin()
|
if q.Join != nil {
|
||||||
|
join = q.Join.parseJoin()
|
||||||
|
}
|
||||||
groupBy := ""
|
groupBy := ""
|
||||||
if q.Group != "" {
|
if q.Group != "" {
|
||||||
g := strings.Builder{}
|
g := strings.Builder{}
|
||||||
|
@ -262,12 +264,16 @@ func BuildQuerySql(q QueryCondition) (r string, args []any, err error) {
|
||||||
if q.Offset > 0 {
|
if q.Offset > 0 {
|
||||||
l = fmt.Sprintf(" %s offset %d", l, q.Offset)
|
l = fmt.Sprintf(" %s offset %d", l, q.Offset)
|
||||||
}
|
}
|
||||||
r = fmt.Sprintf(tp, q.Fields, table, j, w, groupBy, h, q.Order.parseOrderBy(), l)
|
order := ""
|
||||||
|
if q.Order != nil {
|
||||||
|
order = q.Order.parseOrderBy()
|
||||||
|
}
|
||||||
|
r = fmt.Sprintf(tp, q.Fields, table, join, where, groupBy, having, order, l)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func findScanner[T Model](db dbQuery, ctx context.Context, fn func(T), q QueryCondition) (err error) {
|
func findScanner[T Model](db dbQuery, ctx context.Context, fn func(T), q *QueryCondition) (err error) {
|
||||||
setTable[T](&q)
|
setTable[T](q)
|
||||||
s, args, err := BuildQuerySql(q)
|
s, args, err := BuildQuerySql(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -281,33 +287,59 @@ func findScanner[T Model](db dbQuery, ctx context.Context, fn func(T), q QueryCo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindScannerFromDB[T Model](db dbQuery, ctx context.Context, fn func(T), q QueryCondition) error {
|
func FindScannerFromDB[T Model](db dbQuery, ctx context.Context, fn func(T), q *QueryCondition) error {
|
||||||
return findScanner[T](db, ctx, fn, q)
|
return findScanner[T](db, ctx, fn, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindScanner[T Model](ctx context.Context, fn func(T), q QueryCondition) error {
|
func FindScanner[T Model](ctx context.Context, fn func(T), q *QueryCondition) error {
|
||||||
return findScanner[T](globalBb, ctx, fn, q)
|
return findScanner[T](globalBb, ctx, fn, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Gets[T Model](ctx context.Context, q QueryCondition) (T, error) {
|
func Gets[T Model](ctx context.Context, q *QueryCondition) (T, error) {
|
||||||
return gets[T](globalBb, ctx, q)
|
return gets[T](globalBb, ctx, q)
|
||||||
}
|
}
|
||||||
func GetsFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) (T, error) {
|
func GetsFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (T, error) {
|
||||||
return gets[T](db, ctx, q)
|
return gets[T](db, ctx, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gets[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r T, err error) {
|
func gets[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r T, err error) {
|
||||||
setTable[T](&q)
|
setTable[T](q)
|
||||||
|
if len(q.Relation) < 1 {
|
||||||
|
s, args, er := BuildQuerySql(q)
|
||||||
|
if er != nil {
|
||||||
|
err = er
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = db.Get(ctx, &r, s, args...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = parseRelation(false, db, ctx, &r, q)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRelation(isMultiple bool, db dbQuery, ctx context.Context, r any, q *QueryCondition) (err error) {
|
||||||
|
fn, fns := Relation(db, ctx, r, q)
|
||||||
|
for _, f := range fn {
|
||||||
|
f()
|
||||||
|
}
|
||||||
s, args, err := BuildQuerySql(q)
|
s, args, err := BuildQuerySql(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = db.Get(ctx, &r, s, args...)
|
if isMultiple {
|
||||||
|
err = db.Select(ctx, r, s, args...)
|
||||||
|
} else {
|
||||||
|
err = db.Get(ctx, r, s, args...)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(q.Relation) > 0 {
|
for _, f := range fns {
|
||||||
err = Relation[T](db, ctx, &r, &q)
|
err = f()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
func TestFinds(t *testing.T) {
|
func TestFinds(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model] struct {
|
type testCase[T Model] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -66,7 +66,7 @@ func TestChunkFind(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
perLimit int
|
perLimit int
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model] struct {
|
type testCase[T Model] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -118,7 +118,7 @@ func TestChunk(t *testing.T) {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
perLimit int
|
perLimit int
|
||||||
fn func(rows T) (R, bool)
|
fn func(rows T) (R, bool)
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model, R any] struct {
|
type testCase[T Model, R any] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -179,7 +179,7 @@ func TestChunk(t *testing.T) {
|
||||||
func TestPagination(t *testing.T) {
|
func TestPagination(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
page int
|
page int
|
||||||
pageSize int
|
pageSize int
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ func TestColumn(t *testing.T) {
|
||||||
type args[V Model, T any] struct {
|
type args[V Model, T any] struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
fn func(V) (T, bool)
|
fn func(V) (T, bool)
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[V Model, T any] struct {
|
type testCase[V Model, T any] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -354,7 +354,7 @@ func Test_getToStringMap(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -409,7 +409,7 @@ func Test_findToStringMap(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -484,7 +484,7 @@ func Test_findScanner(t *testing.T) {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
fn func(T)
|
fn func(T)
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model] struct {
|
type testCase[T Model] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -547,7 +547,7 @@ func Test_gets(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model] struct {
|
type testCase[T Model] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -585,7 +585,7 @@ func Test_finds(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
db dbQuery
|
db dbQuery
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model] struct {
|
type testCase[T Model] struct {
|
||||||
name string
|
name string
|
||||||
|
@ -648,7 +648,7 @@ func Test_finds(t *testing.T) {
|
||||||
func TestGets(t *testing.T) {
|
func TestGets(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
q QueryCondition
|
q *QueryCondition
|
||||||
}
|
}
|
||||||
type testCase[T Model] struct {
|
type testCase[T Model] struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -3,6 +3,7 @@ package model
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fthvgb1/wp-go/helper"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -13,15 +14,19 @@ func setTable[T Model](q *QueryCondition) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Relation[T Model](db dbQuery, ctx context.Context, r *T, q *QueryCondition) (err error) {
|
func Relation(db dbQuery, ctx context.Context, r any, q *QueryCondition) ([]func(), []func() error) {
|
||||||
var rr T
|
var fn []func()
|
||||||
t := reflect.TypeOf(rr)
|
var fns []func() error
|
||||||
|
t := reflect.TypeOf(r).Elem()
|
||||||
v := reflect.ValueOf(r).Elem()
|
v := reflect.ValueOf(r).Elem()
|
||||||
for tableTag, relation := range q.Relation {
|
for tableTag, relation := range q.Relation {
|
||||||
if tableTag == "" {
|
if tableTag == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
tableTag := tableTag
|
||||||
|
relation := relation
|
||||||
for i := 0; i < t.NumField(); i++ {
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
i := i
|
||||||
tag := t.Field(i).Tag
|
tag := t.Field(i).Tag
|
||||||
table, ok := tag.Lookup("table")
|
table, ok := tag.Lookup("table")
|
||||||
if !ok || table == "" {
|
if !ok || table == "" {
|
||||||
|
@ -31,6 +36,14 @@ func Relation[T Model](db dbQuery, ctx context.Context, r *T, q *QueryCondition)
|
||||||
if tables[len(tables)-1] != tableTag {
|
if tables[len(tables)-1] != tableTag {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
foreignKey := tag.Get("foreignKey")
|
||||||
|
if foreignKey == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
localKey := tag.Get("local")
|
||||||
|
if localKey == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if relation == nil {
|
if relation == nil {
|
||||||
relation = &QueryCondition{
|
relation = &QueryCondition{
|
||||||
Fields: "*",
|
Fields: "*",
|
||||||
|
@ -42,40 +55,48 @@ func Relation[T Model](db dbQuery, ctx context.Context, r *T, q *QueryCondition)
|
||||||
for ; j < t.NumField(); j++ {
|
for ; j < t.NumField(); j++ {
|
||||||
vvv, ok := t.Field(j).Tag.Lookup("db")
|
vvv, ok := t.Field(j).Tag.Lookup("db")
|
||||||
if ok && vvv == tag.Get("local") {
|
if ok && vvv == tag.Get("local") {
|
||||||
id = fmt.Sprintf("%v", v.Field(j).Interface())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
if relation.WithJoin {
|
||||||
var w any = relation.Where
|
from := strings.Split(q.From, " ")
|
||||||
if w == nil {
|
fn = append(fn, func() {
|
||||||
w = SqlBuilder{}
|
qq := helper.GetContextVal(ctx, "ancestorsQueryCondition", q)
|
||||||
|
qq.Join = append(q.Join, SqlBuilder{
|
||||||
|
{"left join", table, fmt.Sprintf("%s.%s=%s.%s", tables[len(tables)-1], foreignKey, from[len(from)-1], localKey)},
|
||||||
|
}...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fns = append(fns, func() error {
|
||||||
|
{
|
||||||
|
var w any = relation.Where
|
||||||
|
if w == nil {
|
||||||
|
w = SqlBuilder{}
|
||||||
|
}
|
||||||
|
ww, ok := w.(SqlBuilder)
|
||||||
|
if ok {
|
||||||
|
id = fmt.Sprintf("%v", v.Field(j).Interface())
|
||||||
|
ww = append(ww, SqlBuilder{{
|
||||||
|
foreignKey, "=", id, "int",
|
||||||
|
}}...)
|
||||||
|
relation.Where = ww
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ww, ok := w.(SqlBuilder)
|
var err error
|
||||||
if ok {
|
vv := reflect.New(v.Field(i).Type().Elem()).Interface()
|
||||||
ww = append(ww, SqlBuilder{{
|
switch tag.Get("relation") {
|
||||||
tag.Get("foreignKey"), "=", id, "int",
|
case "hasOne":
|
||||||
}}...)
|
err = parseRelation(false, db, ctx, vv, relation)
|
||||||
relation.Where = ww
|
case "hasMany":
|
||||||
|
err = parseRelation(true, db, ctx, vv, relation)
|
||||||
}
|
}
|
||||||
}
|
if err != nil {
|
||||||
sq, args, er := BuildQuerySql(*relation)
|
return err
|
||||||
if er != nil {
|
}
|
||||||
err = er
|
v.Field(i).Set(reflect.ValueOf(vv))
|
||||||
return
|
return nil
|
||||||
}
|
})
|
||||||
vv := reflect.New(v.Field(i).Type().Elem()).Interface()
|
|
||||||
switch tag.Get("relation") {
|
|
||||||
case "hasOne":
|
|
||||||
err = db.Get(ctx, vv, sq, args...)
|
|
||||||
case "hasMany":
|
|
||||||
err = db.Select(ctx, vv, sq, args...)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
v.Field(i).Set(reflect.ValueOf(vv))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return fn, fns
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user