2020-08-10 15:04:57 +00:00
|
|
|
// Copyright 2020 beego
|
2020-08-07 13:45:24 +00:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package orm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
|
|
|
"reflect"
|
|
|
|
"time"
|
2020-08-18 14:31:06 +00:00
|
|
|
|
2020-08-20 14:25:37 +00:00
|
|
|
"github.com/astaxie/beego/pkg/infrastructure/utils"
|
2020-08-07 13:45:24 +00:00
|
|
|
)
|
|
|
|
|
2020-08-10 15:04:57 +00:00
|
|
|
const (
|
2020-08-18 14:31:06 +00:00
|
|
|
TxNameKey = "TxName"
|
2020-08-10 15:04:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var _ Ormer = new(filterOrmDecorator)
|
|
|
|
var _ TxOrmer = new(filterOrmDecorator)
|
2020-08-07 13:45:24 +00:00
|
|
|
|
|
|
|
type filterOrmDecorator struct {
|
|
|
|
ormer
|
|
|
|
TxBeginner
|
|
|
|
TxCommitter
|
|
|
|
|
|
|
|
root Filter
|
|
|
|
|
|
|
|
insideTx bool
|
|
|
|
txStartTime time.Time
|
|
|
|
txName string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFilterOrmDecorator(delegate Ormer, filterChains ...FilterChain) Ormer {
|
|
|
|
res := &filterOrmDecorator{
|
|
|
|
ormer: delegate,
|
|
|
|
TxBeginner: delegate,
|
2020-08-18 14:31:06 +00:00
|
|
|
root: func(ctx context.Context, inv *Invocation) []interface{} {
|
|
|
|
return inv.execute(ctx)
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := len(filterChains) - 1; i >= 0; i-- {
|
|
|
|
node := filterChains[i]
|
|
|
|
res.root = node(res.root)
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFilterTxOrmDecorator(delegate TxOrmer, root Filter, txName string) TxOrmer {
|
|
|
|
res := &filterOrmDecorator{
|
|
|
|
ormer: delegate,
|
|
|
|
TxCommitter: delegate,
|
|
|
|
root: root,
|
|
|
|
insideTx: true,
|
|
|
|
txStartTime: time.Now(),
|
2020-08-10 15:04:57 +00:00
|
|
|
txName: txName,
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Read(md interface{}, cols ...string) error {
|
|
|
|
return f.ReadWithCtx(context.Background(), md, cols...)
|
|
|
|
}
|
|
|
|
|
2020-08-18 14:31:06 +00:00
|
|
|
func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
2020-08-07 13:45:24 +00:00
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "ReadWithCtx",
|
|
|
|
Args: []interface{}{md, cols},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
err := f.ormer.ReadWithCtx(c, md, cols...)
|
|
|
|
return []interface{}{err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return f.convertError(res[0])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error {
|
|
|
|
return f.ReadForUpdateWithCtx(context.Background(), md, cols...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "ReadForUpdateWithCtx",
|
|
|
|
Args: []interface{}{md, cols},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
err := f.ormer.ReadForUpdateWithCtx(c, md, cols...)
|
|
|
|
return []interface{}{err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return f.convertError(res[0])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
|
|
|
return f.ReadOrCreateWithCtx(context.Background(), md, col1, cols...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
|
|
|
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "ReadOrCreateWithCtx",
|
|
|
|
Args: []interface{}{md, col1, cols},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
ok, res, err := f.ormer.ReadOrCreateWithCtx(c, md, col1, cols...)
|
|
|
|
return []interface{}{ok, res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(bool), res[1].(int64), f.convertError(res[2])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 14:25:37 +00:00
|
|
|
func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
|
2020-08-07 13:45:24 +00:00
|
|
|
return f.LoadRelatedWithCtx(context.Background(), md, name, args...)
|
|
|
|
}
|
|
|
|
|
2020-08-20 14:25:37 +00:00
|
|
|
func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
|
2020-08-07 13:45:24 +00:00
|
|
|
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "LoadRelatedWithCtx",
|
|
|
|
Args: []interface{}{md, name, args},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.ormer.LoadRelatedWithCtx(c, md, name, args...)
|
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(int64), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer {
|
|
|
|
return f.QueryM2MWithCtx(context.Background(), md, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer {
|
|
|
|
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "QueryM2MWithCtx",
|
|
|
|
Args: []interface{}{md, name},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res := f.ormer.QueryM2MWithCtx(c, md, name)
|
|
|
|
return []interface{}{res}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
if res[0] == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return res[0].(QueryM2Mer)
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QuerySeter {
|
|
|
|
return f.QueryTableWithCtx(context.Background(), ptrStructOrTableName)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter {
|
|
|
|
var (
|
|
|
|
name string
|
2020-08-10 15:04:57 +00:00
|
|
|
md interface{}
|
|
|
|
mi *modelInfo
|
2020-08-07 13:45:24 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if table, ok := ptrStructOrTableName.(string); ok {
|
|
|
|
name = table
|
|
|
|
} else {
|
|
|
|
name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName)))
|
|
|
|
md = ptrStructOrTableName
|
|
|
|
}
|
|
|
|
|
|
|
|
if m, ok := modelCache.getByFullName(name); ok {
|
|
|
|
mi = m
|
|
|
|
}
|
|
|
|
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "QueryTableWithCtx",
|
|
|
|
Args: []interface{}{ptrStructOrTableName},
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-10 15:04:57 +00:00
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res := f.ormer.QueryTableWithCtx(c, ptrStructOrTableName)
|
|
|
|
return []interface{}{res}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
|
|
|
|
if res[0] == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return res[0].(QuerySeter)
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) DBStats() *sql.DBStats {
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "DBStats",
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res := f.ormer.DBStats()
|
|
|
|
return []interface{}{res}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(context.Background(), inv)
|
|
|
|
|
|
|
|
if res[0] == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return res[0].(*sql.DBStats)
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) {
|
|
|
|
return f.InsertWithCtx(context.Background(), md)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "InsertWithCtx",
|
|
|
|
Args: []interface{}{md},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.ormer.InsertWithCtx(c, md)
|
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(int64), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
|
|
|
|
return f.InsertOrUpdateWithCtx(context.Background(), md, colConflitAndArgs...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "InsertOrUpdateWithCtx",
|
|
|
|
Args: []interface{}{md, colConflitAndArgs},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.ormer.InsertOrUpdateWithCtx(c, md, colConflitAndArgs...)
|
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(int64), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) InsertMulti(bulk int, mds interface{}) (int64, error) {
|
|
|
|
return f.InsertMultiWithCtx(context.Background(), bulk, mds)
|
|
|
|
}
|
|
|
|
|
|
|
|
// InsertMultiWithCtx uses the first element's model info
|
|
|
|
func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
|
|
|
|
var (
|
2020-08-18 14:31:06 +00:00
|
|
|
md interface{}
|
|
|
|
mi *modelInfo
|
2020-08-07 13:45:24 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
sind := reflect.Indirect(reflect.ValueOf(mds))
|
|
|
|
|
|
|
|
if (sind.Kind() == reflect.Array || sind.Kind() == reflect.Slice) && sind.Len() > 0 {
|
|
|
|
ind := reflect.Indirect(sind.Index(0))
|
|
|
|
md = ind.Interface()
|
|
|
|
mi, _ = modelCache.getByMd(md)
|
|
|
|
}
|
|
|
|
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "InsertMultiWithCtx",
|
|
|
|
Args: []interface{}{bulk, mds},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.ormer.InsertMultiWithCtx(c, bulk, mds)
|
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(int64), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, error) {
|
|
|
|
return f.UpdateWithCtx(context.Background(), md, cols...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "UpdateWithCtx",
|
|
|
|
Args: []interface{}{md, cols},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.ormer.UpdateWithCtx(c, md, cols...)
|
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(int64), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, error) {
|
|
|
|
return f.DeleteWithCtx(context.Background(), md, cols...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
|
|
|
mi, _ := modelCache.getByMd(md)
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "DeleteWithCtx",
|
|
|
|
Args: []interface{}{md, cols},
|
|
|
|
Md: md,
|
|
|
|
mi: mi,
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.ormer.DeleteWithCtx(c, md, cols...)
|
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(int64), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Raw(query string, args ...interface{}) RawSeter {
|
|
|
|
return f.RawWithCtx(context.Background(), query, args...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "RawWithCtx",
|
|
|
|
Args: []interface{}{query, args},
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res := f.ormer.RawWithCtx(c, query, args...)
|
|
|
|
return []interface{}{res}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
|
|
|
|
if res[0] == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return res[0].(RawSeter)
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Driver() Driver {
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "Driver",
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res := f.ormer.Driver()
|
|
|
|
return []interface{}{res}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(context.Background(), inv)
|
|
|
|
if res[0] == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return res[0].(Driver)
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Begin() (TxOrmer, error) {
|
|
|
|
return f.BeginWithCtxAndOpts(context.Background(), nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
|
|
|
|
return f.BeginWithCtxAndOpts(ctx, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
|
|
|
|
return f.BeginWithCtxAndOpts(context.Background(), opts)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "BeginWithCtxAndOpts",
|
|
|
|
Args: []interface{}{opts},
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
res, err := f.TxBeginner.BeginWithCtxAndOpts(c, opts)
|
2020-08-10 15:04:57 +00:00
|
|
|
res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(c))
|
2020-08-18 14:31:06 +00:00
|
|
|
return []interface{}{res, err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return res[0].(TxOrmer), f.convertError(res[1])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
2020-08-10 15:04:57 +00:00
|
|
|
func (f *filterOrmDecorator) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
|
2020-08-07 13:45:24 +00:00
|
|
|
return f.DoTxWithCtxAndOpts(context.Background(), nil, task)
|
|
|
|
}
|
|
|
|
|
2020-08-10 15:04:57 +00:00
|
|
|
func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
2020-08-07 13:45:24 +00:00
|
|
|
return f.DoTxWithCtxAndOpts(ctx, nil, task)
|
|
|
|
}
|
|
|
|
|
2020-08-10 15:04:57 +00:00
|
|
|
func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
2020-08-07 13:45:24 +00:00
|
|
|
return f.DoTxWithCtxAndOpts(context.Background(), opts, task)
|
|
|
|
}
|
|
|
|
|
2020-08-10 15:04:57 +00:00
|
|
|
func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
|
2020-08-07 13:45:24 +00:00
|
|
|
inv := &Invocation{
|
|
|
|
Method: "DoTxWithCtxAndOpts",
|
|
|
|
Args: []interface{}{opts, task},
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
|
|
|
TxName: getTxNameFromCtx(ctx),
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
err := doTxTemplate(f, c, opts, task)
|
|
|
|
return []interface{}{err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(ctx, inv)
|
|
|
|
return f.convertError(res[0])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Commit() error {
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "Commit",
|
|
|
|
Args: []interface{}{},
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
|
|
|
TxName: f.txName,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
err := f.TxCommitter.Commit()
|
|
|
|
return []interface{}{err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(context.Background(), inv)
|
|
|
|
return f.convertError(res[0])
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) Rollback() error {
|
|
|
|
inv := &Invocation{
|
|
|
|
Method: "Rollback",
|
|
|
|
Args: []interface{}{},
|
|
|
|
InsideTx: f.insideTx,
|
|
|
|
TxStartTime: f.txStartTime,
|
|
|
|
TxName: f.txName,
|
2020-08-18 14:31:06 +00:00
|
|
|
f: func(c context.Context) []interface{} {
|
|
|
|
err := f.TxCommitter.Rollback()
|
|
|
|
return []interface{}{err}
|
2020-08-07 13:45:24 +00:00
|
|
|
},
|
|
|
|
}
|
2020-08-18 14:31:06 +00:00
|
|
|
res := f.root(context.Background(), inv)
|
|
|
|
return f.convertError(res[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *filterOrmDecorator) convertError(v interface{}) error {
|
|
|
|
if v == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return v.(error)
|
2020-08-07 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getTxNameFromCtx(ctx context.Context) string {
|
|
|
|
txName := ""
|
|
|
|
if n, ok := ctx.Value(TxNameKey).(string); ok {
|
|
|
|
txName = n
|
|
|
|
}
|
|
|
|
return txName
|
|
|
|
}
|