mirror of
https://github.com/astaxie/beego.git
synced 2025-06-13 08:30:39 +00:00
Merge develop-2.0
This commit is contained in:
@ -485,7 +485,12 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
|
||||
if isMulti {
|
||||
return res.RowsAffected()
|
||||
}
|
||||
return res.LastInsertId()
|
||||
|
||||
lastInsertId, err:=res.LastInsertId()
|
||||
if err != nil {
|
||||
DebugLog.Println("[WARN] return LastInsertId error:", err)
|
||||
}
|
||||
return lastInsertId, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...common.KV
|
||||
return al, nil
|
||||
}
|
||||
|
||||
func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...common.KV)(*alias, error){
|
||||
func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...common.KV) (*alias, error) {
|
||||
kvs := common.NewKVs(params...)
|
||||
|
||||
var stmtCache *lru.Cache
|
||||
@ -430,7 +430,6 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...common
|
||||
al *alias
|
||||
)
|
||||
|
||||
|
||||
db, err = sql.Open(driverName, dataSource)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error())
|
||||
|
@ -76,7 +76,6 @@ func TestRegisterDataBase_MaxStmtCacheSize841(t *testing.T) {
|
||||
assert.Equal(t, al.DB.stmtDecoratorsLimit, 841)
|
||||
}
|
||||
|
||||
|
||||
func TestDBCache(t *testing.T) {
|
||||
dataBaseCache.add("test1", &alias{})
|
||||
dataBaseCache.add("default", &alias{})
|
||||
|
@ -150,7 +150,12 @@ func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, nam
|
||||
if isMulti {
|
||||
return res.RowsAffected()
|
||||
}
|
||||
return res.LastInsertId()
|
||||
|
||||
lastInsertId, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
DebugLog.Println("[WARN] return LastInsertId error:", err)
|
||||
}
|
||||
return lastInsertId, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -27,6 +27,7 @@ import (
|
||||
var _ Ormer = new(DoNothingOrm)
|
||||
|
||||
type DoNothingOrm struct {
|
||||
|
||||
}
|
||||
|
||||
func (d *DoNothingOrm) Read(md interface{}, cols ...string) error {
|
||||
@ -149,19 +150,19 @@ func (d *DoNothingOrm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOpti
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (d *DoNothingOrm) DoTx(task func(txOrm TxOrmer) error) error {
|
||||
func (d *DoNothingOrm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DoNothingOrm) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error {
|
||||
func (d *DoNothingOrm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DoNothingOrm) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||
func (d *DoNothingOrm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DoNothingOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||
func (d *DoNothingOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -22,7 +22,7 @@ import (
|
||||
// don't forget to call next(...) inside your Filter
|
||||
type FilterChain func(next Filter) Filter
|
||||
|
||||
// Filter's behavior is a little big strang.
|
||||
// Filter's behavior is a little big strange.
|
||||
// it's only be called when users call methods of Ormer
|
||||
type Filter func(ctx context.Context, inv *Invocation)
|
||||
|
||||
@ -31,6 +31,6 @@ var globalFilterChains = make([]FilterChain, 0, 4)
|
||||
// AddGlobalFilterChain adds a new FilterChain
|
||||
// All orm instances built after this invocation will use this filterChain,
|
||||
// but instances built before this invocation will not be affected
|
||||
func AddGlobalFilterChain(filterChain FilterChain) {
|
||||
globalFilterChains = append(globalFilterChains, filterChain)
|
||||
}
|
||||
func AddGlobalFilterChain(filterChain ...FilterChain) {
|
||||
globalFilterChains = append(globalFilterChains, filterChain...)
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ func TestDefaultValueFilterChainBuilder_FilterChain(t *testing.T) {
|
||||
entity = &DefaultValueTestEntity{}
|
||||
orm.RegisterModel(entity)
|
||||
|
||||
|
||||
_, _ = o.InsertOrUpdate(entity)
|
||||
assert.Equal(t, 12, entity.Age)
|
||||
assert.Equal(t, 13, entity.AgeInOldStyle)
|
||||
@ -66,7 +65,7 @@ type defaultValueTestOrm struct {
|
||||
}
|
||||
|
||||
type DefaultValueTestEntity struct {
|
||||
Id int`orm:pk`
|
||||
Id int
|
||||
Age int `default:"12"`
|
||||
AgeInOldStyle int `orm:"default(13);bee()"`
|
||||
AgeIgnore int
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -16,6 +16,7 @@ package opentracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
|
||||
@ -27,6 +28,8 @@ import (
|
||||
// for example:
|
||||
// if we want to trace QuerySetter
|
||||
// actually we trace invoking "QueryTable" and "QueryTableWithCtx"
|
||||
// the method Begin*, Commit and Rollback are ignored.
|
||||
// When use using those methods, it means that they want to manager their transaction manually, so we won't handle them.
|
||||
type FilterChainBuilder struct {
|
||||
// CustomSpanFunc users are able to custom their span
|
||||
CustomSpanFunc func(span opentracing.Span, ctx context.Context, inv *orm.Invocation)
|
||||
@ -35,25 +38,34 @@ type FilterChainBuilder struct {
|
||||
func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
|
||||
return func(ctx context.Context, inv *orm.Invocation) {
|
||||
operationName := builder.operationName(ctx, inv)
|
||||
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
|
||||
defer span.Finish()
|
||||
|
||||
next(spanCtx, inv)
|
||||
span.SetTag("Method", inv.Method)
|
||||
span.SetTag("Table", inv.GetTableName())
|
||||
span.SetTag("InsideTx", inv.InsideTx)
|
||||
span.SetTag("TxName", spanCtx.Value(orm.TxNameKey))
|
||||
|
||||
if builder.CustomSpanFunc != nil {
|
||||
builder.CustomSpanFunc(span, spanCtx, inv)
|
||||
if strings.HasPrefix(inv.Method, "Begin") || inv.Method == "Commit" || inv.Method == "Rollback" {
|
||||
next(ctx, inv)
|
||||
return
|
||||
}
|
||||
|
||||
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
|
||||
defer span.Finish()
|
||||
next(spanCtx, inv)
|
||||
builder.buildSpan(span, spanCtx, inv)
|
||||
}
|
||||
}
|
||||
|
||||
func (builder *FilterChainBuilder) buildSpan(span opentracing.Span, ctx context.Context, inv *orm.Invocation) {
|
||||
span.SetTag("orm.method", inv.Method)
|
||||
span.SetTag("orm.table", inv.GetTableName())
|
||||
span.SetTag("orm.insideTx", inv.InsideTx)
|
||||
span.SetTag("orm.txName", ctx.Value(orm.TxNameKey))
|
||||
span.SetTag("span.kind", "client")
|
||||
span.SetTag("component", "beego")
|
||||
|
||||
if builder.CustomSpanFunc != nil {
|
||||
builder.CustomSpanFunc(span, ctx, inv)
|
||||
}
|
||||
}
|
||||
|
||||
func (builder *FilterChainBuilder) operationName(ctx context.Context, inv *orm.Invocation) string {
|
||||
if n, ok := ctx.Value(orm.TxNameKey).(string); ok {
|
||||
return inv.Method + "#" + n
|
||||
return inv.Method + "#tx(" + n + ")"
|
||||
}
|
||||
return inv.Method + "#" + inv.GetTableName()
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -40,4 +40,4 @@ func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||
TxStartTime: time.Now(),
|
||||
}
|
||||
builder.FilterChain(next)(context.Background(), inv)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -22,7 +22,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const TxNameKey = "TxName"
|
||||
const (
|
||||
TxNameKey = "TxName"
|
||||
)
|
||||
|
||||
var _ Ormer = new(filterOrmDecorator)
|
||||
var _ TxOrmer = new(filterOrmDecorator)
|
||||
|
||||
type filterOrmDecorator struct {
|
||||
ormer
|
||||
@ -41,7 +46,7 @@ func NewFilterOrmDecorator(delegate Ormer, filterChains ...FilterChain) Ormer {
|
||||
ormer: delegate,
|
||||
TxBeginner: delegate,
|
||||
root: func(ctx context.Context, inv *Invocation) {
|
||||
inv.execute()
|
||||
inv.execute(ctx)
|
||||
},
|
||||
}
|
||||
|
||||
@ -59,7 +64,7 @@ func NewFilterTxOrmDecorator(delegate TxOrmer, root Filter, txName string) TxOrm
|
||||
root: root,
|
||||
insideTx: true,
|
||||
txStartTime: time.Now(),
|
||||
txName: txName,
|
||||
txName: txName,
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -77,8 +82,8 @@ func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, co
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
err = f.ormer.ReadWithCtx(ctx, md, cols...)
|
||||
f: func(c context.Context) {
|
||||
err = f.ormer.ReadWithCtx(c, md, cols...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -99,8 +104,8 @@ func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interf
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
err = f.ormer.ReadForUpdateWithCtx(ctx, md, cols...)
|
||||
f: func(c context.Context) {
|
||||
err = f.ormer.ReadForUpdateWithCtx(c, md, cols...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -126,8 +131,8 @@ func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interfa
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
ok, res, err = f.ormer.ReadOrCreateWithCtx(ctx, md, col1, cols...)
|
||||
f: func(c context.Context) {
|
||||
ok, res, err = f.ormer.ReadOrCreateWithCtx(c, md, col1, cols...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -152,8 +157,8 @@ func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interfac
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.ormer.LoadRelatedWithCtx(ctx, md, name, args...)
|
||||
f: func(c context.Context) {
|
||||
res, err = f.ormer.LoadRelatedWithCtx(c, md, name, args...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -177,8 +182,8 @@ func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{}
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res = f.ormer.QueryM2MWithCtx(ctx, md, name)
|
||||
f: func(c context.Context) {
|
||||
res = f.ormer.QueryM2MWithCtx(c, md, name)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -191,10 +196,10 @@ func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QueryS
|
||||
|
||||
func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter {
|
||||
var (
|
||||
res QuerySeter
|
||||
res QuerySeter
|
||||
name string
|
||||
md interface{}
|
||||
mi *modelInfo
|
||||
md interface{}
|
||||
mi *modelInfo
|
||||
)
|
||||
|
||||
if table, ok := ptrStructOrTableName.(string); ok {
|
||||
@ -213,10 +218,10 @@ func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrT
|
||||
Args: []interface{}{ptrStructOrTableName},
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
Md: md,
|
||||
mi: mi,
|
||||
f: func() {
|
||||
res = f.ormer.QueryTableWithCtx(ctx, ptrStructOrTableName)
|
||||
Md: md,
|
||||
mi: mi,
|
||||
f: func(c context.Context) {
|
||||
res = f.ormer.QueryTableWithCtx(c, ptrStructOrTableName)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -231,7 +236,7 @@ func (f *filterOrmDecorator) DBStats() *sql.DBStats {
|
||||
Method: "DBStats",
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
f: func(c context.Context) {
|
||||
res = f.ormer.DBStats()
|
||||
},
|
||||
}
|
||||
@ -256,8 +261,8 @@ func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{})
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.ormer.InsertWithCtx(ctx, md)
|
||||
f: func(c context.Context) {
|
||||
res, err = f.ormer.InsertWithCtx(c, md)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -281,8 +286,8 @@ func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md inter
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.ormer.InsertOrUpdateWithCtx(ctx, md, colConflitAndArgs...)
|
||||
f: func(c context.Context) {
|
||||
res, err = f.ormer.InsertOrUpdateWithCtx(c, md, colConflitAndArgs...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -317,8 +322,8 @@ func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, m
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.ormer.InsertMultiWithCtx(ctx, bulk, mds)
|
||||
f: func(c context.Context) {
|
||||
res, err = f.ormer.InsertMultiWithCtx(c, bulk, mds)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -342,8 +347,8 @@ func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{},
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.ormer.UpdateWithCtx(ctx, md, cols...)
|
||||
f: func(c context.Context) {
|
||||
res, err = f.ormer.UpdateWithCtx(c, md, cols...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -367,8 +372,8 @@ func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{},
|
||||
mi: mi,
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.ormer.DeleteWithCtx(ctx, md, cols...)
|
||||
f: func(c context.Context) {
|
||||
res, err = f.ormer.DeleteWithCtx(c, md, cols...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -388,8 +393,8 @@ func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args
|
||||
Args: []interface{}{query, args},
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res = f.ormer.RawWithCtx(ctx, query, args...)
|
||||
f: func(c context.Context) {
|
||||
res = f.ormer.RawWithCtx(c, query, args...)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -404,7 +409,7 @@ func (f *filterOrmDecorator) Driver() Driver {
|
||||
Method: "Driver",
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
f: func(c context.Context) {
|
||||
res = f.ormer.Driver()
|
||||
},
|
||||
}
|
||||
@ -434,28 +439,28 @@ func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql.
|
||||
Args: []interface{}{opts},
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
f: func() {
|
||||
res, err = f.TxBeginner.BeginWithCtxAndOpts(ctx, opts)
|
||||
res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(ctx))
|
||||
f: func(c context.Context) {
|
||||
res, err = f.TxBeginner.BeginWithCtxAndOpts(c, opts)
|
||||
res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(c))
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (f *filterOrmDecorator) DoTx(task func(txOrm TxOrmer) error) error {
|
||||
func (f *filterOrmDecorator) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return f.DoTxWithCtxAndOpts(context.Background(), nil, task)
|
||||
}
|
||||
|
||||
func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error {
|
||||
func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return f.DoTxWithCtxAndOpts(ctx, nil, task)
|
||||
}
|
||||
|
||||
func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||
func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return f.DoTxWithCtxAndOpts(context.Background(), opts, task)
|
||||
}
|
||||
|
||||
func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(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
|
||||
)
|
||||
@ -466,8 +471,8 @@ func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.T
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
TxName: getTxNameFromCtx(ctx),
|
||||
f: func() {
|
||||
err = f.TxBeginner.DoTxWithCtxAndOpts(ctx, opts, task)
|
||||
f: func(c context.Context) {
|
||||
err = doTxTemplate(f, c, opts, task)
|
||||
},
|
||||
}
|
||||
f.root(ctx, inv)
|
||||
@ -484,7 +489,7 @@ func (f *filterOrmDecorator) Commit() error {
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
TxName: f.txName,
|
||||
f: func() {
|
||||
f: func(c context.Context) {
|
||||
err = f.TxCommitter.Commit()
|
||||
},
|
||||
}
|
||||
@ -502,7 +507,7 @@ func (f *filterOrmDecorator) Rollback() error {
|
||||
InsideTx: f.insideTx,
|
||||
TxStartTime: f.txStartTime,
|
||||
TxName: f.txName,
|
||||
f: func() {
|
||||
f: func(c context.Context) {
|
||||
err = f.TxCommitter.Rollback()
|
||||
},
|
||||
}
|
||||
@ -517,4 +522,3 @@ func getTxNameFromCtx(ctx context.Context) string {
|
||||
}
|
||||
return txName
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -131,49 +131,49 @@ func TestFilterOrmDecorator_DoTx(t *testing.T) {
|
||||
o := &filterMockOrm{}
|
||||
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||
return func(ctx context.Context, inv *Invocation) {
|
||||
assert.Equal(t, "DoTxWithCtxAndOpts", inv.Method)
|
||||
assert.Equal(t, 2, len(inv.Args))
|
||||
assert.Equal(t, "", inv.GetTableName())
|
||||
assert.False(t, inv.InsideTx)
|
||||
if inv.Method == "DoTxWithCtxAndOpts" {
|
||||
assert.Equal(t, 2, len(inv.Args))
|
||||
assert.Equal(t, "", inv.GetTableName())
|
||||
assert.False(t, inv.InsideTx)
|
||||
}
|
||||
|
||||
next(ctx, inv)
|
||||
}
|
||||
})
|
||||
|
||||
err := od.DoTx(func(txOrm TxOrmer) error {
|
||||
return errors.New("tx error")
|
||||
err := od.DoTx(func(c context.Context, txOrm TxOrmer) error {
|
||||
return nil
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, "tx error", err.Error())
|
||||
|
||||
err = od.DoTxWithCtx(context.Background(), func(txOrm TxOrmer) error {
|
||||
return errors.New("tx ctx error")
|
||||
err = od.DoTxWithCtx(context.Background(), func(c context.Context, txOrm TxOrmer) error {
|
||||
return nil
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, "tx ctx error", err.Error())
|
||||
|
||||
err = od.DoTxWithOpts(nil, func(txOrm TxOrmer) error {
|
||||
return errors.New("tx opts error")
|
||||
err = od.DoTxWithOpts(nil, func(c context.Context, txOrm TxOrmer) error {
|
||||
return nil
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, "tx opts error", err.Error())
|
||||
|
||||
|
||||
od = NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||
return func(ctx context.Context, inv *Invocation) {
|
||||
assert.Equal(t, "DoTxWithCtxAndOpts", inv.Method)
|
||||
assert.Equal(t, 2, len(inv.Args))
|
||||
assert.Equal(t, "", inv.GetTableName())
|
||||
assert.Equal(t, "do tx name", inv.TxName)
|
||||
assert.False(t, inv.InsideTx)
|
||||
if inv.Method == "DoTxWithCtxAndOpts" {
|
||||
assert.Equal(t, 2, len(inv.Args))
|
||||
assert.Equal(t, "", inv.GetTableName())
|
||||
assert.Equal(t, "do tx name", inv.TxName)
|
||||
assert.False(t, inv.InsideTx)
|
||||
}
|
||||
next(ctx, inv)
|
||||
}
|
||||
})
|
||||
|
||||
ctx := context.WithValue(context.Background(), TxNameKey, "do tx name")
|
||||
err = od.DoTxWithCtxAndOpts(ctx, nil, func(txOrm TxOrmer) error {
|
||||
return errors.New("tx ctx opts error")
|
||||
err = od.DoTxWithCtxAndOpts(ctx, nil, func(c context.Context, txOrm TxOrmer) error {
|
||||
return nil
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, "tx ctx opts error", err.Error())
|
||||
}
|
||||
|
||||
func TestFilterOrmDecorator_Driver(t *testing.T) {
|
||||
@ -348,6 +348,8 @@ func TestFilterOrmDecorator_ReadOrCreate(t *testing.T) {
|
||||
assert.Equal(t, int64(13), i)
|
||||
}
|
||||
|
||||
var _ Ormer = new(filterMockOrm)
|
||||
|
||||
// filterMockOrm is only used in this test file
|
||||
type filterMockOrm struct {
|
||||
DoNothingOrm
|
||||
@ -377,8 +379,8 @@ func (f *filterMockOrm) InsertWithCtx(ctx context.Context, md interface{}) (int6
|
||||
return 100, errors.New("insert error")
|
||||
}
|
||||
|
||||
func (f *filterMockOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||
return task(nil)
|
||||
func (f *filterMockOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(c context.Context, txOrm TxOrmer) error) error {
|
||||
return task(ctx, nil)
|
||||
}
|
||||
|
||||
func (f *filterMockOrm) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -28,4 +28,5 @@ func TestAddGlobalFilterChain(t *testing.T) {
|
||||
}
|
||||
})
|
||||
assert.Equal(t, 1, len(globalFilterChains))
|
||||
globalFilterChains = nil
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 beego
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -15,6 +15,7 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -22,29 +23,29 @@ import (
|
||||
type Invocation struct {
|
||||
Method string
|
||||
// Md may be nil in some cases. It depends on method
|
||||
Md interface{}
|
||||
Md interface{}
|
||||
// the args are all arguments except context.Context
|
||||
Args []interface{}
|
||||
Args []interface{}
|
||||
|
||||
mi *modelInfo
|
||||
// f is the Orm operation
|
||||
f func()
|
||||
f func(ctx context.Context)
|
||||
|
||||
// insideTx indicates whether this is inside a transaction
|
||||
InsideTx bool
|
||||
InsideTx bool
|
||||
TxStartTime time.Time
|
||||
TxName string
|
||||
TxName string
|
||||
}
|
||||
|
||||
func (inv *Invocation) GetTableName() string {
|
||||
if inv.mi != nil{
|
||||
if inv.mi != nil {
|
||||
return inv.mi.table
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (inv *Invocation) execute() {
|
||||
inv.f()
|
||||
func (inv *Invocation) execute(ctx context.Context) {
|
||||
inv.f(ctx)
|
||||
}
|
||||
|
||||
// GetPkFieldName return the primary key of this table
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -28,7 +28,6 @@ import (
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
// As tidb can't use go get, so disable the tidb testing now
|
||||
// _ "github.com/pingcap/tidb"
|
||||
|
||||
)
|
||||
|
||||
// A slice string field.
|
||||
@ -422,6 +421,11 @@ type PtrPk struct {
|
||||
Positive bool
|
||||
}
|
||||
|
||||
type StrPk struct {
|
||||
Id string `orm:"column(id);size(64);pk"`
|
||||
Value string
|
||||
}
|
||||
|
||||
var DBARGS = struct {
|
||||
Driver string
|
||||
Source string
|
||||
|
@ -528,19 +528,24 @@ func (o *orm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxO
|
||||
return taskTxOrm, nil
|
||||
}
|
||||
|
||||
func (o *orm) DoTx(task func(txOrm TxOrmer) error) error {
|
||||
func (o *orm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return o.DoTxWithCtx(context.Background(), task)
|
||||
}
|
||||
|
||||
func (o *orm) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error {
|
||||
func (o *orm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return o.DoTxWithCtxAndOpts(ctx, nil, task)
|
||||
}
|
||||
|
||||
func (o *orm) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||
func (o *orm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return o.DoTxWithCtxAndOpts(context.Background(), opts, task)
|
||||
}
|
||||
|
||||
func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||
func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
return doTxTemplate(o, ctx, opts, task)
|
||||
}
|
||||
|
||||
func doTxTemplate(o TxBeginner, ctx context.Context, opts *sql.TxOptions,
|
||||
task func(ctx context.Context, txOrm TxOrmer) error) error {
|
||||
_txOrm, err := o.BeginWithCtxAndOpts(ctx, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -559,9 +564,8 @@ func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var taskTxOrm = _txOrm
|
||||
err = task(taskTxOrm)
|
||||
err = task(ctx, taskTxOrm)
|
||||
panicked = false
|
||||
return err
|
||||
}
|
||||
@ -588,18 +592,11 @@ func NewOrm() Ormer {
|
||||
|
||||
// NewOrmUsingDB create new orm with the name
|
||||
func NewOrmUsingDB(aliasName string) Ormer {
|
||||
o := new(orm)
|
||||
if al, ok := dataBaseCache.get(aliasName); ok {
|
||||
o.alias = al
|
||||
if Debug {
|
||||
o.db = newDbQueryLog(al, al.DB)
|
||||
} else {
|
||||
o.db = al.DB
|
||||
}
|
||||
return newDBWithAlias(al)
|
||||
} else {
|
||||
panic(fmt.Errorf("<Ormer.Using> unknown db alias name `%s`", aliasName))
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// NewOrmWithDB create a new ormer object with specify *sql.DB for query
|
||||
@ -609,14 +606,21 @@ func NewOrmWithDB(driverName, aliasName string, db *sql.DB, params ...common.KV)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newDBWithAlias(al), nil
|
||||
}
|
||||
|
||||
func newDBWithAlias(al *alias) Ormer {
|
||||
o := new(orm)
|
||||
o.alias = al
|
||||
|
||||
if Debug {
|
||||
o.db = newDbQueryLog(o.alias, db)
|
||||
o.db = newDbQueryLog(al, al.DB)
|
||||
} else {
|
||||
o.db = db
|
||||
o.db = al.DB
|
||||
}
|
||||
|
||||
return o, nil
|
||||
if len(globalFilterChains) > 0 {
|
||||
return NewFilterOrmDecorator(o, globalFilterChains...)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
@ -202,6 +202,7 @@ func TestSyncDb(t *testing.T) {
|
||||
RegisterModel(new(UintPk))
|
||||
RegisterModel(new(PtrPk))
|
||||
RegisterModel(new(Index))
|
||||
RegisterModel(new(StrPk))
|
||||
|
||||
err := RunSyncdb("default", true, Debug)
|
||||
throwFail(t, err)
|
||||
@ -227,6 +228,7 @@ func TestRegisterModels(t *testing.T) {
|
||||
RegisterModel(new(UintPk))
|
||||
RegisterModel(new(PtrPk))
|
||||
RegisterModel(new(Index))
|
||||
RegisterModel(new(StrPk))
|
||||
|
||||
BootStrap()
|
||||
|
||||
@ -2524,4 +2526,21 @@ func TestInsertOrUpdate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrPkInsert(t *testing.T) {
|
||||
RegisterModel(new(StrPk))
|
||||
value := `StrPkValues(*56`
|
||||
strPk := &StrPk{
|
||||
Id: "1",
|
||||
Value: value,
|
||||
}
|
||||
|
||||
var err error
|
||||
_, err = dORM.Insert(strPk)
|
||||
throwFailNow(t, AssertIs(err, nil))
|
||||
|
||||
var vForTesting StrPk
|
||||
err = dORM.QueryTable(new(StrPk)).Filter(`id`, `1`).One(&vForTesting)
|
||||
throwFailNow(t, AssertIs(err, nil))
|
||||
throwFailNow(t, AssertIs(vForTesting.Value, value))
|
||||
}
|
||||
|
||||
|
@ -96,10 +96,10 @@ type TxBeginner interface {
|
||||
BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error)
|
||||
|
||||
//closure control transaction
|
||||
DoTx(task func(txOrm TxOrmer) error) error
|
||||
DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error
|
||||
DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error
|
||||
DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error
|
||||
DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||
DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||
DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||
DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||
}
|
||||
|
||||
type TxCommitter interface {
|
||||
|
Reference in New Issue
Block a user