Refactor orm filter

This commit is contained in:
Ming Deng 2020-08-18 14:31:06 +00:00
parent 63599c0032
commit 7fe4eaef50
54 changed files with 269 additions and 256 deletions

View File

@ -1,6 +1,6 @@
goimports -l pkg goimports -w -format-only pkg
goimports -l examples goimports -w -format-only examples
ineffassign . ineffassign .

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,5 +17,4 @@ package bean
// ApplicationContext define for future // ApplicationContext define for future
// when we decide to support DI, IoC, this will be core API // when we decide to support DI, IoC, this will be core API
type ApplicationContext interface { type ApplicationContext interface {
} }

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -22,4 +22,4 @@ import (
type AutoWireBeanFactory interface { type AutoWireBeanFactory interface {
// AutoWire will wire the bean. // AutoWire will wire the bean.
AutoWire(ctx context.Context, appCtx ApplicationContext, bean interface{}) error AutoWire(ctx context.Context, appCtx ApplicationContext, bean interface{}) error
} }

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@ package bean
import ( import (
"context" "context"
"time" "time"
) )
// TimeTypeAdapter process the time.Time // TimeTypeAdapter process the time.Time
@ -29,7 +28,7 @@ type TimeTypeAdapter struct {
// and if the DftValue == now // and if the DftValue == now
// time.Now() is returned // time.Now() is returned
func (t *TimeTypeAdapter) DefaultValue(ctx context.Context, dftValue string) (interface{}, error) { func (t *TimeTypeAdapter) DefaultValue(ctx context.Context, dftValue string) (interface{}, error) {
if dftValue == "now"{ if dftValue == "now" {
return time.Now(), nil return time.Now(), nil
} }
return time.Parse(t.Layout, dftValue) return time.Parse(t.Layout, dftValue)

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -1,8 +1,10 @@
package param package param
import "testing" import (
import "reflect" "reflect"
import "time" "testing"
"time"
)
type testDefinition struct { type testDefinition struct {
strValue string strValue string

View File

@ -21,9 +21,10 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/astaxie/beego/pkg/context"
"os" "os"
"path/filepath" "path/filepath"
"github.com/astaxie/beego/pkg/context"
) )
func TestGetInt(t *testing.T) { func TestGetInt(t *testing.T) {

View File

@ -18,10 +18,11 @@ import (
"database/sql" "database/sql"
"errors" "errors"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints"
"reflect" "reflect"
"strings" "strings"
"time" "time"
"github.com/astaxie/beego/pkg/orm/hints"
) )
const ( const (
@ -490,7 +491,7 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
}else{ } else {
return lastInsertId, nil return lastInsertId, nil
} }
} }
@ -598,7 +599,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
}else{ } else {
return lastInsertId, nil return lastInsertId, nil
} }
} }
@ -1954,5 +1955,3 @@ func (d *dbBase) GenerateSpecifyIndex(tableName string, useIndex int, indexes []
return fmt.Sprintf(` %s INDEX(%s) `, useWay, strings.Join(s, `,`)) return fmt.Sprintf(` %s INDEX(%s) `, useWay, strings.Join(s, `,`))
} }

View File

@ -18,10 +18,11 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints"
"sync" "sync"
"time" "time"
"github.com/astaxie/beego/pkg/orm/hints"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
"github.com/astaxie/beego/pkg/common" "github.com/astaxie/beego/pkg/common"

View File

@ -15,10 +15,11 @@
package orm package orm
import ( import (
"github.com/astaxie/beego/pkg/orm/hints"
"testing" "testing"
"time" "time"
"github.com/astaxie/beego/pkg/orm/hints"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@ -169,7 +169,7 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
}else{ } else {
return lastInsertId, nil return lastInsertId, nil
} }
} }

View File

@ -16,8 +16,9 @@ package orm
import ( import (
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints"
"strings" "strings"
"github.com/astaxie/beego/pkg/orm/hints"
) )
// oracle operators. // oracle operators.
@ -155,7 +156,7 @@ func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, nam
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
}else{ } else {
return lastInsertId, nil return lastInsertId, nil
} }
} }

View File

@ -92,7 +92,6 @@ func (d *dbBasePostgres) MaxLimit() uint64 {
return 0 return 0
} }
// postgresql quote is ". // postgresql quote is ".
func (d *dbBasePostgres) TableQuote() string { func (d *dbBasePostgres) TableQuote() string {
return `"` return `"`

View File

@ -17,10 +17,11 @@ package orm
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints"
"reflect" "reflect"
"strings" "strings"
"time" "time"
"github.com/astaxie/beego/pkg/orm/hints"
) )
// sqlite operators. // sqlite operators.
@ -173,7 +174,6 @@ func (d *dbBaseSqlite) GenerateSpecifyIndex(tableName string, useIndex int, inde
} }
} }
// create new sqlite dbBaser. // create new sqlite dbBaser.
func newdbBaseSqlite() dbBaser { func newdbBaseSqlite() dbBaser {
b := new(dbBaseSqlite) b := new(dbBaseSqlite)

View File

@ -473,7 +473,7 @@ func (t *dbTables) getLimitSQL(mi *modelInfo, offset int64, limit int64) (limits
} }
// getIndexSql generate index sql. // getIndexSql generate index sql.
func (t *dbTables) getIndexSql(tableName string,useIndex int, indexes []string) (clause string) { func (t *dbTables) getIndexSql(tableName string, useIndex int, indexes []string) (clause string) {
if len(indexes) == 0 { if len(indexes) == 0 {
return return
} }

View File

@ -17,6 +17,7 @@ package orm
import ( import (
"context" "context"
"database/sql" "database/sql"
"github.com/astaxie/beego/pkg/common" "github.com/astaxie/beego/pkg/common"
) )
@ -27,7 +28,6 @@ import (
var _ Ormer = new(DoNothingOrm) var _ Ormer = new(DoNothingOrm)
type DoNothingOrm struct { type DoNothingOrm struct {
} }
func (d *DoNothingOrm) Read(md interface{}, cols ...string) error { func (d *DoNothingOrm) Read(md interface{}, cols ...string) error {
@ -54,11 +54,11 @@ func (d *DoNothingOrm) ReadOrCreateWithCtx(ctx context.Context, md interface{},
return false, 0, nil return false, 0, nil
} }
func (d *DoNothingOrm) LoadRelated(md interface{}, name string, args ...common.KV) (int64, error) { func (d *DoNothingOrm) LoadRelated(md interface{}, name string, args ...common.KV) (int64, error) {
return 0, nil return 0, nil
} }
func (d *DoNothingOrm) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...common.KV) (int64, error) { func (d *DoNothingOrm) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...common.KV) (int64, error) {
return 0, nil return 0, nil
} }

View File

@ -24,7 +24,11 @@ type FilterChain func(next Filter) Filter
// Filter's behavior is a little big strange. // Filter's behavior is a little big strange.
// it's only be called when users call methods of Ormer // it's only be called when users call methods of Ormer
type Filter func(ctx context.Context, inv *Invocation) // return value is an array. it's a little bit hard to understand,
// for example, the Ormer's Read method only return error
// so the filter processing this method should return an array whose first element is error
// and, Ormer's ReadOrCreateWithCtx return three values, so the Filter's result should contains three values
type Filter func(ctx context.Context, inv *Invocation) []interface{}
var globalFilterChains = make([]FilterChain, 0, 4) var globalFilterChains = make([]FilterChain, 0, 4)

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -76,7 +76,7 @@ func NewDefaultValueFilterChainBuilder(typeAdapters map[string]bean.TypeAdapter,
} }
func (d *DefaultValueFilterChainBuilder) FilterChain(next orm.Filter) orm.Filter { func (d *DefaultValueFilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
return func(ctx context.Context, inv *orm.Invocation) { return func(ctx context.Context, inv *orm.Invocation) []interface{} {
switch inv.Method { switch inv.Method {
case "Insert", "InsertWithCtx": case "Insert", "InsertWithCtx":
d.handleInsert(ctx, inv) d.handleInsert(ctx, inv)
@ -88,7 +88,7 @@ func (d *DefaultValueFilterChainBuilder) FilterChain(next orm.Filter) orm.Filter
d.handleInsertMulti(ctx, inv) d.handleInsertMulti(ctx, inv)
break break
} }
next(ctx, inv) return next(ctx, inv)
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2020 // Copyright 2020
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@ -36,17 +36,17 @@ type FilterChainBuilder struct {
} }
func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter { func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
return func(ctx context.Context, inv *orm.Invocation) { return func(ctx context.Context, inv *orm.Invocation) []interface{} {
operationName := builder.operationName(ctx, inv) operationName := builder.operationName(ctx, inv)
if strings.HasPrefix(inv.Method, "Begin") || inv.Method == "Commit" || inv.Method == "Rollback" { if strings.HasPrefix(inv.Method, "Begin") || inv.Method == "Commit" || inv.Method == "Rollback" {
next(ctx, inv) return next(ctx, inv)
return
} }
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName) span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
defer span.Finish() defer span.Finish()
next(spanCtx, inv) res := next(spanCtx, inv)
builder.buildSpan(span, spanCtx, inv) builder.buildSpan(span, spanCtx, inv)
return res
} }
} }

View File

@ -25,8 +25,9 @@ import (
) )
func TestFilterChainBuilder_FilterChain(t *testing.T) { func TestFilterChainBuilder_FilterChain(t *testing.T) {
next := func(ctx context.Context, inv *orm.Invocation) { next := func(ctx context.Context, inv *orm.Invocation) []interface{} {
inv.TxName = "Hello" inv.TxName = "Hello"
return []interface{}{}
} }
builder := &FilterChainBuilder{ builder := &FilterChainBuilder{

View File

@ -56,15 +56,16 @@ func NewFilterChainBuilder() *FilterChainBuilder {
} }
func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter { func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
return func(ctx context.Context, inv *orm.Invocation) { return func(ctx context.Context, inv *orm.Invocation) []interface{} {
startTime := time.Now() startTime := time.Now()
next(ctx, inv) res := next(ctx, inv)
endTime := time.Now() endTime := time.Now()
dur := (endTime.Sub(startTime)) / time.Millisecond dur := (endTime.Sub(startTime)) / time.Millisecond
// if the TPS is too large, here may be some problem // if the TPS is too large, here may be some problem
// thinking about using goroutine pool // thinking about using goroutine pool
go builder.report(ctx, inv, dur) go builder.report(ctx, inv, dur)
return res
} }
} }

View File

@ -28,8 +28,9 @@ func TestFilterChainBuilder_FilterChain(t *testing.T) {
builder := NewFilterChainBuilder() builder := NewFilterChainBuilder()
assert.NotNil(t, builder.summaryVec) assert.NotNil(t, builder.summaryVec)
filter := builder.FilterChain(func(ctx context.Context, inv *orm.Invocation) { filter := builder.FilterChain(func(ctx context.Context, inv *orm.Invocation) []interface{} {
inv.Method = "coming" inv.Method = "coming"
return []interface{}{}
}) })
assert.NotNil(t, filter) assert.NotNil(t, filter)

View File

@ -17,13 +17,14 @@ package orm
import ( import (
"context" "context"
"database/sql" "database/sql"
"github.com/astaxie/beego/pkg/common"
"reflect" "reflect"
"time" "time"
"github.com/astaxie/beego/pkg/common"
) )
const ( const (
TxNameKey = "TxName" TxNameKey = "TxName"
) )
var _ Ormer = new(filterOrmDecorator) var _ Ormer = new(filterOrmDecorator)
@ -45,8 +46,8 @@ func NewFilterOrmDecorator(delegate Ormer, filterChains ...FilterChain) Ormer {
res := &filterOrmDecorator{ res := &filterOrmDecorator{
ormer: delegate, ormer: delegate,
TxBeginner: delegate, TxBeginner: delegate,
root: func(ctx context.Context, inv *Invocation) { root: func(ctx context.Context, inv *Invocation) []interface{} {
inv.execute(ctx) return inv.execute(ctx)
}, },
} }
@ -73,7 +74,7 @@ func (f *filterOrmDecorator) Read(md interface{}, cols ...string) error {
return f.ReadWithCtx(context.Background(), md, cols...) return f.ReadWithCtx(context.Background(), md, cols...)
} }
func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) (err error) { func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "ReadWithCtx", Method: "ReadWithCtx",
@ -82,12 +83,13 @@ func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, co
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
err = f.ormer.ReadWithCtx(c, md, cols...) err := f.ormer.ReadWithCtx(c, md, cols...)
return []interface{}{err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return err return f.convertError(res[0])
} }
func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error { func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error {
@ -95,7 +97,6 @@ func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error
} }
func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error { func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
var err error
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "ReadForUpdateWithCtx", Method: "ReadForUpdateWithCtx",
@ -104,12 +105,13 @@ func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interf
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
err = f.ormer.ReadForUpdateWithCtx(c, md, cols...) err := f.ormer.ReadForUpdateWithCtx(c, md, cols...)
return []interface{}{err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return err return f.convertError(res[0])
} }
func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) { func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
@ -117,11 +119,6 @@ func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...s
} }
func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) { func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
var (
ok bool
res int64
err error
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
@ -131,12 +128,13 @@ func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interfa
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
ok, res, err = f.ormer.ReadOrCreateWithCtx(c, md, col1, cols...) ok, res, err := f.ormer.ReadOrCreateWithCtx(c, md, col1, cols...)
return []interface{}{ok, res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return ok, res, err return res[0].(bool), res[1].(int64), f.convertError(res[2])
} }
func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...common.KV) (int64, error) { func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...common.KV) (int64, error) {
@ -144,10 +142,6 @@ func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...co
} }
func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...common.KV) (int64, error) { func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...common.KV) (int64, error) {
var (
res int64
err error
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
@ -157,12 +151,13 @@ func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interfac
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.ormer.LoadRelatedWithCtx(c, md, name, args...) res, err := f.ormer.LoadRelatedWithCtx(c, md, name, args...)
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(int64), f.convertError(res[1])
} }
func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer { func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer {
@ -170,9 +165,6 @@ func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer {
} }
func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer { func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer {
var (
res QueryM2Mer
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
@ -182,12 +174,16 @@ func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{}
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res = f.ormer.QueryM2MWithCtx(c, md, name) res := f.ormer.QueryM2MWithCtx(c, md, name)
return []interface{}{res}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res if res[0] == nil {
return nil
}
return res[0].(QueryM2Mer)
} }
func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QuerySeter { func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QuerySeter {
@ -196,7 +192,6 @@ func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QueryS
func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter { func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter {
var ( var (
res QuerySeter
name string name string
md interface{} md interface{}
mi *modelInfo mi *modelInfo
@ -220,28 +215,36 @@ func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrT
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
Md: md, Md: md,
mi: mi, mi: mi,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res = f.ormer.QueryTableWithCtx(c, ptrStructOrTableName) res := f.ormer.QueryTableWithCtx(c, ptrStructOrTableName)
return []interface{}{res}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res
if res[0] == nil {
return nil
}
return res[0].(QuerySeter)
} }
func (f *filterOrmDecorator) DBStats() *sql.DBStats { func (f *filterOrmDecorator) DBStats() *sql.DBStats {
var (
res *sql.DBStats
)
inv := &Invocation{ inv := &Invocation{
Method: "DBStats", Method: "DBStats",
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res = f.ormer.DBStats() res := f.ormer.DBStats()
return []interface{}{res}
}, },
} }
f.root(context.Background(), inv) res := f.root(context.Background(), inv)
return res
if res[0] == nil {
return nil
}
return res[0].(*sql.DBStats)
} }
func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) { func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) {
@ -249,10 +252,6 @@ func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) {
} }
func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) { func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
var (
res int64
err error
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "InsertWithCtx", Method: "InsertWithCtx",
@ -261,12 +260,13 @@ func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{})
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.ormer.InsertWithCtx(c, md) res, err := f.ormer.InsertWithCtx(c, md)
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(int64), f.convertError(res[1])
} }
func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) { func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
@ -274,10 +274,6 @@ func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ..
} }
func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) { func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
var (
res int64
err error
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "InsertOrUpdateWithCtx", Method: "InsertOrUpdateWithCtx",
@ -286,12 +282,13 @@ func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md inter
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.ormer.InsertOrUpdateWithCtx(c, md, colConflitAndArgs...) res, err := f.ormer.InsertOrUpdateWithCtx(c, md, colConflitAndArgs...)
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(int64), f.convertError(res[1])
} }
func (f *filterOrmDecorator) InsertMulti(bulk int, mds interface{}) (int64, error) { func (f *filterOrmDecorator) InsertMulti(bulk int, mds interface{}) (int64, error) {
@ -301,10 +298,8 @@ func (f *filterOrmDecorator) InsertMulti(bulk int, mds interface{}) (int64, erro
// InsertMultiWithCtx uses the first element's model info // InsertMultiWithCtx uses the first element's model info
func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) { func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
var ( var (
res int64 md interface{}
err error mi *modelInfo
md interface{}
mi *modelInfo
) )
sind := reflect.Indirect(reflect.ValueOf(mds)) sind := reflect.Indirect(reflect.ValueOf(mds))
@ -322,12 +317,13 @@ func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, m
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.ormer.InsertMultiWithCtx(c, bulk, mds) res, err := f.ormer.InsertMultiWithCtx(c, bulk, mds)
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(int64), f.convertError(res[1])
} }
func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, error) { func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, error) {
@ -335,10 +331,6 @@ func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, erro
} }
func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
var (
res int64
err error
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "UpdateWithCtx", Method: "UpdateWithCtx",
@ -347,12 +339,13 @@ func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{},
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.ormer.UpdateWithCtx(c, md, cols...) res, err := f.ormer.UpdateWithCtx(c, md, cols...)
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(int64), f.convertError(res[1])
} }
func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, error) { func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, error) {
@ -360,10 +353,6 @@ func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, erro
} }
func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
var (
res int64
err error
)
mi, _ := modelCache.getByMd(md) mi, _ := modelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "DeleteWithCtx", Method: "DeleteWithCtx",
@ -372,12 +361,13 @@ func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{},
mi: mi, mi: mi,
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.ormer.DeleteWithCtx(c, md, cols...) res, err := f.ormer.DeleteWithCtx(c, md, cols...)
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(int64), f.convertError(res[1])
} }
func (f *filterOrmDecorator) Raw(query string, args ...interface{}) RawSeter { func (f *filterOrmDecorator) Raw(query string, args ...interface{}) RawSeter {
@ -385,36 +375,39 @@ func (f *filterOrmDecorator) Raw(query string, args ...interface{}) RawSeter {
} }
func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter { func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
var (
res RawSeter
)
inv := &Invocation{ inv := &Invocation{
Method: "RawWithCtx", Method: "RawWithCtx",
Args: []interface{}{query, args}, Args: []interface{}{query, args},
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res = f.ormer.RawWithCtx(c, query, args...) res := f.ormer.RawWithCtx(c, query, args...)
return []interface{}{res}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res
if res[0] == nil {
return nil
}
return res[0].(RawSeter)
} }
func (f *filterOrmDecorator) Driver() Driver { func (f *filterOrmDecorator) Driver() Driver {
var (
res Driver
)
inv := &Invocation{ inv := &Invocation{
Method: "Driver", Method: "Driver",
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res = f.ormer.Driver() res := f.ormer.Driver()
return []interface{}{res}
}, },
} }
f.root(context.Background(), inv) res := f.root(context.Background(), inv)
return res if res[0] == nil {
return nil
}
return res[0].(Driver)
} }
func (f *filterOrmDecorator) Begin() (TxOrmer, error) { func (f *filterOrmDecorator) Begin() (TxOrmer, error) {
@ -430,22 +423,19 @@ func (f *filterOrmDecorator) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error)
} }
func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) { func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
var (
res TxOrmer
err error
)
inv := &Invocation{ inv := &Invocation{
Method: "BeginWithCtxAndOpts", Method: "BeginWithCtxAndOpts",
Args: []interface{}{opts}, Args: []interface{}{opts},
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
res, err = f.TxBeginner.BeginWithCtxAndOpts(c, opts) res, err := f.TxBeginner.BeginWithCtxAndOpts(c, opts)
res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(c)) res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(c))
return []interface{}{res, err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return res, err return res[0].(TxOrmer), f.convertError(res[1])
} }
func (f *filterOrmDecorator) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error { func (f *filterOrmDecorator) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
@ -461,58 +451,58 @@ func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(ctx con
} }
func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
var (
err error
)
inv := &Invocation{ inv := &Invocation{
Method: "DoTxWithCtxAndOpts", Method: "DoTxWithCtxAndOpts",
Args: []interface{}{opts, task}, Args: []interface{}{opts, task},
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
TxName: getTxNameFromCtx(ctx), TxName: getTxNameFromCtx(ctx),
f: func(c context.Context) { f: func(c context.Context) []interface{} {
err = doTxTemplate(f, c, opts, task) err := doTxTemplate(f, c, opts, task)
return []interface{}{err}
}, },
} }
f.root(ctx, inv) res := f.root(ctx, inv)
return err return f.convertError(res[0])
} }
func (f *filterOrmDecorator) Commit() error { func (f *filterOrmDecorator) Commit() error {
var (
err error
)
inv := &Invocation{ inv := &Invocation{
Method: "Commit", Method: "Commit",
Args: []interface{}{}, Args: []interface{}{},
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
TxName: f.txName, TxName: f.txName,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
err = f.TxCommitter.Commit() err := f.TxCommitter.Commit()
return []interface{}{err}
}, },
} }
f.root(context.Background(), inv) res := f.root(context.Background(), inv)
return err return f.convertError(res[0])
} }
func (f *filterOrmDecorator) Rollback() error { func (f *filterOrmDecorator) Rollback() error {
var (
err error
)
inv := &Invocation{ inv := &Invocation{
Method: "Rollback", Method: "Rollback",
Args: []interface{}{}, Args: []interface{}{},
InsideTx: f.insideTx, InsideTx: f.insideTx,
TxStartTime: f.txStartTime, TxStartTime: f.txStartTime,
TxName: f.txName, TxName: f.txName,
f: func(c context.Context) { f: func(c context.Context) []interface{} {
err = f.TxCommitter.Rollback() err := f.TxCommitter.Rollback()
return []interface{}{err}
}, },
} }
f.root(context.Background(), inv) res := f.root(context.Background(), inv)
return err return f.convertError(res[0])
}
func (f *filterOrmDecorator) convertError(v interface{}) error {
if v == nil {
return nil
}
return v.(error)
} }
func getTxNameFromCtx(ctx context.Context) string { func getTxNameFromCtx(ctx context.Context) string {

View File

@ -18,10 +18,11 @@ import (
"context" "context"
"database/sql" "database/sql"
"errors" "errors"
"github.com/astaxie/beego/pkg/common"
"sync" "sync"
"testing" "testing"
"github.com/astaxie/beego/pkg/common"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -31,11 +32,11 @@ func TestFilterOrmDecorator_Read(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "ReadWithCtx", inv.Method) assert.Equal(t, "ReadWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
next(ctx, inv) return next(ctx, inv)
} }
}) })
@ -50,7 +51,7 @@ func TestFilterOrmDecorator_BeginTx(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
if inv.Method == "BeginWithCtxAndOpts" { if inv.Method == "BeginWithCtxAndOpts" {
assert.Equal(t, 1, len(inv.Args)) assert.Equal(t, 1, len(inv.Args))
assert.Equal(t, "", inv.GetTableName()) assert.Equal(t, "", inv.GetTableName())
@ -69,7 +70,7 @@ func TestFilterOrmDecorator_BeginTx(t *testing.T) {
t.Fail() t.Fail()
} }
next(ctx, inv) return next(ctx, inv)
} }
}) })
to, err := od.Begin() to, err := od.Begin()
@ -98,11 +99,11 @@ func TestFilterOrmDecorator_BeginTx(t *testing.T) {
func TestFilterOrmDecorator_DBStats(t *testing.T) { func TestFilterOrmDecorator_DBStats(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "DBStats", inv.Method) assert.Equal(t, "DBStats", inv.Method)
assert.Equal(t, 0, len(inv.Args)) assert.Equal(t, 0, len(inv.Args))
assert.Equal(t, "", inv.GetTableName()) assert.Equal(t, "", inv.GetTableName())
next(ctx, inv) return next(ctx, inv)
} }
}) })
res := od.DBStats() res := od.DBStats()
@ -114,11 +115,11 @@ func TestFilterOrmDecorator_Delete(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "DeleteWithCtx", inv.Method) assert.Equal(t, "DeleteWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
next(ctx, inv) return next(ctx, inv)
} }
}) })
res, err := od.Delete(&FilterTestEntity{}) res, err := od.Delete(&FilterTestEntity{})
@ -130,14 +131,13 @@ func TestFilterOrmDecorator_Delete(t *testing.T) {
func TestFilterOrmDecorator_DoTx(t *testing.T) { func TestFilterOrmDecorator_DoTx(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
if inv.Method == "DoTxWithCtxAndOpts" { if inv.Method == "DoTxWithCtxAndOpts" {
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "", inv.GetTableName()) assert.Equal(t, "", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
} }
return next(ctx, inv)
next(ctx, inv)
} }
}) })
@ -156,16 +156,15 @@ func TestFilterOrmDecorator_DoTx(t *testing.T) {
}) })
assert.NotNil(t, err) assert.NotNil(t, err)
od = NewFilterOrmDecorator(o, func(next Filter) Filter { od = NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
if inv.Method == "DoTxWithCtxAndOpts" { if inv.Method == "DoTxWithCtxAndOpts" {
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "", inv.GetTableName()) assert.Equal(t, "", inv.GetTableName())
assert.Equal(t, "do tx name", inv.TxName) assert.Equal(t, "do tx name", inv.TxName)
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
} }
next(ctx, inv) return next(ctx, inv)
} }
}) })
@ -179,12 +178,12 @@ func TestFilterOrmDecorator_DoTx(t *testing.T) {
func TestFilterOrmDecorator_Driver(t *testing.T) { func TestFilterOrmDecorator_Driver(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "Driver", inv.Method) assert.Equal(t, "Driver", inv.Method)
assert.Equal(t, 0, len(inv.Args)) assert.Equal(t, 0, len(inv.Args))
assert.Equal(t, "", inv.GetTableName()) assert.Equal(t, "", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
res := od.Driver() res := od.Driver()
@ -195,12 +194,12 @@ func TestFilterOrmDecorator_Insert(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "InsertWithCtx", inv.Method) assert.Equal(t, "InsertWithCtx", inv.Method)
assert.Equal(t, 1, len(inv.Args)) assert.Equal(t, 1, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
@ -214,12 +213,12 @@ func TestFilterOrmDecorator_InsertMulti(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "InsertMultiWithCtx", inv.Method) assert.Equal(t, "InsertMultiWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
@ -234,12 +233,12 @@ func TestFilterOrmDecorator_InsertOrUpdate(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "InsertOrUpdateWithCtx", inv.Method) assert.Equal(t, "InsertOrUpdateWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
i, err := od.InsertOrUpdate(&FilterTestEntity{}) i, err := od.InsertOrUpdate(&FilterTestEntity{})
@ -251,12 +250,12 @@ func TestFilterOrmDecorator_InsertOrUpdate(t *testing.T) {
func TestFilterOrmDecorator_LoadRelated(t *testing.T) { func TestFilterOrmDecorator_LoadRelated(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "LoadRelatedWithCtx", inv.Method) assert.Equal(t, "LoadRelatedWithCtx", inv.Method)
assert.Equal(t, 3, len(inv.Args)) assert.Equal(t, 3, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
i, err := od.LoadRelated(&FilterTestEntity{}, "hello") i, err := od.LoadRelated(&FilterTestEntity{}, "hello")
@ -268,12 +267,12 @@ func TestFilterOrmDecorator_LoadRelated(t *testing.T) {
func TestFilterOrmDecorator_QueryM2M(t *testing.T) { func TestFilterOrmDecorator_QueryM2M(t *testing.T) {
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "QueryM2MWithCtx", inv.Method) assert.Equal(t, "QueryM2MWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
res := od.QueryM2M(&FilterTestEntity{}, "hello") res := od.QueryM2M(&FilterTestEntity{}, "hello")
@ -284,12 +283,12 @@ func TestFilterOrmDecorator_QueryTable(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "QueryTableWithCtx", inv.Method) assert.Equal(t, "QueryTableWithCtx", inv.Method)
assert.Equal(t, 1, len(inv.Args)) assert.Equal(t, 1, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
res := od.QueryTable(&FilterTestEntity{}) res := od.QueryTable(&FilterTestEntity{})
@ -300,28 +299,28 @@ func TestFilterOrmDecorator_Raw(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "RawWithCtx", inv.Method) assert.Equal(t, "RawWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "", inv.GetTableName()) assert.Equal(t, "", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
res := od.Raw("hh") res := od.Raw("hh")
assert.Nil(t, res) assert.Nil(t, res)
} }
func TestFilterOrmDecorator_ReadForUpdate(t *testing.T) { func TestFilterOrmDecorator_ReadForUpdate(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "ReadForUpdateWithCtx", inv.Method) assert.Equal(t, "ReadForUpdateWithCtx", inv.Method)
assert.Equal(t, 2, len(inv.Args)) assert.Equal(t, 2, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
err := od.ReadForUpdate(&FilterTestEntity{}) err := od.ReadForUpdate(&FilterTestEntity{})
@ -333,12 +332,12 @@ func TestFilterOrmDecorator_ReadOrCreate(t *testing.T) {
register() register()
o := &filterMockOrm{} o := &filterMockOrm{}
od := NewFilterOrmDecorator(o, func(next Filter) Filter { od := NewFilterOrmDecorator(o, func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
assert.Equal(t, "ReadOrCreateWithCtx", inv.Method) assert.Equal(t, "ReadOrCreateWithCtx", inv.Method)
assert.Equal(t, 3, len(inv.Args)) assert.Equal(t, 3, len(inv.Args))
assert.Equal(t, "FILTER_TEST", inv.GetTableName()) assert.Equal(t, "FILTER_TEST", inv.GetTableName())
assert.False(t, inv.InsideTx) assert.False(t, inv.InsideTx)
next(ctx, inv) return next(ctx, inv)
} }
}) })
ok, i, err := od.ReadOrCreate(&FilterTestEntity{}, "name") ok, i, err := od.ReadOrCreate(&FilterTestEntity{}, "name")

View File

@ -23,8 +23,8 @@ import (
func TestAddGlobalFilterChain(t *testing.T) { func TestAddGlobalFilterChain(t *testing.T) {
AddGlobalFilterChain(func(next Filter) Filter { AddGlobalFilterChain(func(next Filter) Filter {
return func(ctx context.Context, inv *Invocation) { return func(ctx context.Context, inv *Invocation) []interface{} {
return next(ctx, inv)
} }
}) })
assert.Equal(t, 1, len(globalFilterChains)) assert.Equal(t, 1, len(globalFilterChains))

View File

@ -15,8 +15,9 @@
package hints package hints
import ( import (
"github.com/astaxie/beego/pkg/common"
"time" "time"
"github.com/astaxie/beego/pkg/common"
) )
const ( const (

View File

@ -15,9 +15,10 @@
package hints package hints
import ( import (
"github.com/stretchr/testify/assert"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
) )
func TestNewHint_time(t *testing.T) { func TestNewHint_time(t *testing.T) {
@ -151,4 +152,4 @@ func TestOrderBy(t *testing.T) {
hint := OrderBy(`-ID`) hint := OrderBy(`-ID`)
assert.Equal(t, hint.GetValue(), `-ID`) assert.Equal(t, hint.GetValue(), `-ID`)
assert.Equal(t, hint.GetKey(), KeyOrderBy) assert.Equal(t, hint.GetKey(), KeyOrderBy)
} }

View File

@ -29,7 +29,7 @@ type Invocation struct {
mi *modelInfo mi *modelInfo
// f is the Orm operation // f is the Orm operation
f func(ctx context.Context) f func(ctx context.Context) []interface{}
// insideTx indicates whether this is inside a transaction // insideTx indicates whether this is inside a transaction
InsideTx bool InsideTx bool
@ -44,8 +44,8 @@ func (inv *Invocation) GetTableName() string {
return "" return ""
} }
func (inv *Invocation) execute(ctx context.Context) { func (inv *Invocation) execute(ctx context.Context) []interface{} {
inv.f(ctx) return inv.f(ctx)
} }
// GetPkFieldName return the primary key of this table // GetPkFieldName return the primary key of this table

View File

@ -18,11 +18,12 @@ import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints"
"os" "os"
"strings" "strings"
"time" "time"
"github.com/astaxie/beego/pkg/orm/hints"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq" _ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
@ -430,7 +431,7 @@ type PtrPk struct {
} }
type StrPk struct { type StrPk struct {
Id string `orm:"column(id);size(64);pk"` Id string `orm:"column(id);size(64);pk"`
Value string Value string
} }

View File

@ -58,12 +58,13 @@ import (
"database/sql" "database/sql"
"errors" "errors"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/common"
"github.com/astaxie/beego/pkg/orm/hints"
"os" "os"
"reflect" "reflect"
"time" "time"
"github.com/astaxie/beego/pkg/common"
"github.com/astaxie/beego/pkg/orm/hints"
"github.com/astaxie/beego/pkg/logs" "github.com/astaxie/beego/pkg/logs"
) )

View File

@ -17,6 +17,7 @@ package orm
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints" "github.com/astaxie/beego/pkg/orm/hints"
) )

View File

@ -17,9 +17,10 @@ package orm
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/pkg/errors"
"reflect" "reflect"
"time" "time"
"github.com/pkg/errors"
) )
// raw sql string prepared statement // raw sql string prepared statement

View File

@ -21,7 +21,6 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/astaxie/beego/pkg/orm/hints"
"io/ioutil" "io/ioutil"
"math" "math"
"os" "os"
@ -32,6 +31,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/astaxie/beego/pkg/orm/hints"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -2565,7 +2566,7 @@ func TestStrPkInsert(t *testing.T) {
Id: pk, Id: pk,
Value: value2, Value: value2,
} }
_, err = dORM.InsertOrUpdate(strPkForUpsert, `id`) _, err = dORM.InsertOrUpdate(strPkForUpsert, `id`)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@ -17,9 +17,10 @@ package orm
import ( import (
"context" "context"
"database/sql" "database/sql"
"github.com/astaxie/beego/pkg/common"
"reflect" "reflect"
"time" "time"
"github.com/astaxie/beego/pkg/common"
) )
// TableNaming is usually used by model // TableNaming is usually used by model
@ -579,5 +580,5 @@ type dbBaser interface {
collectFieldValue(*modelInfo, *fieldInfo, reflect.Value, bool, *time.Location) (interface{}, error) collectFieldValue(*modelInfo, *fieldInfo, reflect.Value, bool, *time.Location) (interface{}, error)
setval(dbQuerier, *modelInfo, []string) error setval(dbQuerier, *modelInfo, []string) error
GenerateSpecifyIndex(tableName string,useIndex int ,indexes []string) string GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string
} }

View File

@ -19,7 +19,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"go/ast" "go/ast"
"golang.org/x/tools/go/packages"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -29,6 +28,8 @@ import (
"strings" "strings"
"unicode" "unicode"
"golang.org/x/tools/go/packages"
"github.com/astaxie/beego/pkg/context/param" "github.com/astaxie/beego/pkg/context/param"
"github.com/astaxie/beego/pkg/logs" "github.com/astaxie/beego/pkg/logs"
"github.com/astaxie/beego/pkg/utils" "github.com/astaxie/beego/pkg/utils"

View File

@ -40,7 +40,7 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/astaxie/beego/pkg" beego "github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/context" "github.com/astaxie/beego/pkg/context"
) )

View File

@ -40,10 +40,11 @@
package authz package authz
import ( import (
"github.com/astaxie/beego/pkg" "net/http"
beego "github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/context" "github.com/astaxie/beego/pkg/context"
"github.com/casbin/casbin" "github.com/casbin/casbin"
"net/http"
) )
// NewAuthorizer returns the authorizer. // NewAuthorizer returns the authorizer.

View File

@ -15,13 +15,14 @@
package authz package authz
import ( import (
"github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/context"
"github.com/astaxie/beego/pkg/plugins/auth"
"github.com/casbin/casbin"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
beego "github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/context"
"github.com/astaxie/beego/pkg/plugins/auth"
"github.com/casbin/casbin"
) )
func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) { func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) {

View File

@ -42,7 +42,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/astaxie/beego/pkg" beego "github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/context" "github.com/astaxie/beego/pkg/context"
) )

View File

@ -21,7 +21,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/astaxie/beego/pkg" beego "github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/context" "github.com/astaxie/beego/pkg/context"
) )

View File

@ -224,7 +224,7 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
c.Do(c.Context(), "SET", sid, "", "EX", rp.maxlifetime) c.Do(c.Context(), "SET", sid, "", "EX", rp.maxlifetime)
} else { } else {
c.Rename(oldsid, sid) c.Rename(oldsid, sid)
c.Expire(sid, time.Duration(rp.maxlifetime) * time.Second) c.Expire(sid, time.Duration(rp.maxlifetime)*time.Second)
} }
return rp.SessionRead(sid) return rp.SessionRead(sid)
} }

View File

@ -33,13 +33,14 @@
package redis_cluster package redis_cluster
import ( import (
"github.com/astaxie/beego/pkg/session"
rediss "github.com/go-redis/redis/v7"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/astaxie/beego/pkg/session"
rediss "github.com/go-redis/redis/v7"
) )
var redispder = &Provider{} var redispder = &Provider{}

View File

@ -33,13 +33,14 @@
package redis_sentinel package redis_sentinel
import ( import (
"github.com/astaxie/beego/pkg/session"
"github.com/go-redis/redis/v7"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/astaxie/beego/pkg/session"
"github.com/go-redis/redis/v7"
) )
var redispder = &Provider{} var redispder = &Provider{}

View File

@ -28,7 +28,7 @@ import (
"github.com/astaxie/beego/pkg/context" "github.com/astaxie/beego/pkg/context"
"github.com/astaxie/beego/pkg/logs" "github.com/astaxie/beego/pkg/logs"
"github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
) )
var errNotStaticRequest = errors.New("request not a static file request") var errNotStaticRequest = errors.New("request not a static file request")

View File

@ -21,7 +21,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/elazarl/go-bindata-assetfs" assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/astaxie/beego/test" "github.com/astaxie/beego/test"

View File

@ -66,7 +66,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/astaxie/beego/pkg" beego "github.com/astaxie/beego/pkg"
"github.com/astaxie/beego/pkg/cache" "github.com/astaxie/beego/pkg/cache"
"github.com/astaxie/beego/pkg/context" "github.com/astaxie/beego/pkg/context"
"github.com/astaxie/beego/pkg/logs" "github.com/astaxie/beego/pkg/logs"

View File

@ -16,13 +16,14 @@ package validation
import ( import (
"fmt" "fmt"
"github.com/astaxie/beego/pkg/logs"
"reflect" "reflect"
"regexp" "regexp"
"strings" "strings"
"sync" "sync"
"time" "time"
"unicode/utf8" "unicode/utf8"
"github.com/astaxie/beego/pkg/logs"
) )
// CanSkipFuncs will skip valid if RequiredFirst is true and the struct field's value is empty // CanSkipFuncs will skip valid if RequiredFirst is true and the struct field's value is empty

View File

@ -11,13 +11,14 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"fmt" "fmt"
"github.com/elazarl/go-bindata-assetfs"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
assetfs "github.com/elazarl/go-bindata-assetfs"
) )
func bindataRead(data []byte, name string) ([]byte, error) { func bindataRead(data []byte, name string) ([]byte, error) {