mirror of
https://github.com/astaxie/beego.git
synced 2024-11-21 21:30:54 +00:00
Refactor orm filter
This commit is contained in:
parent
63599c0032
commit
7fe4eaef50
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
goimports -l pkg
|
goimports -w -format-only pkg
|
||||||
goimports -l examples
|
goimports -w -format-only examples
|
||||||
|
|
||||||
ineffassign .
|
ineffassign .
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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, `,`))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 `"`
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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{
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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")
|
||||||
|
@ -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))
|
||||||
|
@ -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 (
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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{}
|
||||||
|
@ -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{}
|
||||||
|
@ -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")
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user