Merge branch 'develop' into frt/supports_for_4144

# Conflicts:
#	client/orm/orm_queryset.go
This commit is contained in:
Anker Jam
2021-01-09 21:16:27 +08:00
317 changed files with 3113 additions and 1662 deletions

View File

@@ -1,6 +1,6 @@
# beego orm
[![Build Status](https://drone.io/github.com/astaxie/beego/status.png)](https://drone.io/github.com/astaxie/beego/latest)
[![Build Status](https://drone.io/github.com/beego/beego/v2/status.png)](https://drone.io/github.com/beego/beego/v2/latest)
A powerful orm framework for go.
@@ -27,7 +27,7 @@ more features please read the docs
**Install:**
go get github.com/astaxie/beego/orm
go get github.com/beego/beego/v2/orm
## Changelog
@@ -45,7 +45,7 @@ package main
import (
"fmt"
"github.com/astaxie/beego/orm"
"github.com/beego/beego/v2/orm"
_ "github.com/go-sql-driver/mysql" // import your used driver
)

View File

@@ -22,7 +22,7 @@ import (
"strings"
"time"
"github.com/astaxie/beego/client/orm/hints"
"github.com/beego/beego/v2/client/orm/hints"
)
const (
@@ -524,7 +524,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
return 0, fmt.Errorf("`%s` nonsupport InsertOrUpdate in beego", a.DriverName)
}
//Get on the key-value pairs
// Get on the key-value pairs
for _, v := range args {
kv := strings.Split(v, "=")
if len(kv) == 2 {
@@ -559,7 +559,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
updates[i] = v + "=" + valueStr
case DRPostgres:
if conflitValue != nil {
//postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
// postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args0)
updateValues = append(updateValues, conflitValue)
} else {
@@ -584,7 +584,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
if isMulti {
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
}
//conflitValue maybe is a int,can`t use fmt.Sprintf
// conflitValue maybe is a int,can`t use fmt.Sprintf
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
d.ins.ReplaceMarks(&query)

View File

@@ -111,7 +111,7 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
iouStr = "ON DUPLICATE KEY UPDATE"
//Get on the key-value pairs
// Get on the key-value pairs
for _, v := range args {
kv := strings.Split(v, "=")
if len(kv) == 2 {
@@ -155,7 +155,7 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
if isMulti {
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
}
//conflitValue maybe is a int,can`t use fmt.Sprintf
// conflitValue maybe is a int,can`t use fmt.Sprintf
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
d.ins.ReplaceMarks(&query)

View File

@@ -18,7 +18,7 @@ import (
"fmt"
"strings"
"github.com/astaxie/beego/client/orm/hints"
"github.com/beego/beego/v2/client/orm/hints"
)
// oracle operators.
@@ -77,7 +77,7 @@ func (d *dbBaseOracle) DbTypes() map[string]string {
return oracleTypes
}
//ShowTablesQuery show all the tables in database
// ShowTablesQuery show all the tables in database
func (d *dbBaseOracle) ShowTablesQuery() string {
return "SELECT TABLE_NAME FROM USER_TABLES"
}

View File

@@ -21,7 +21,7 @@ import (
"strings"
"time"
"github.com/astaxie/beego/client/orm/hints"
"github.com/beego/beego/v2/client/orm/hints"
)
// sqlite operators.

View File

@@ -18,7 +18,7 @@ import (
"context"
"database/sql"
"github.com/astaxie/beego/core/utils"
"github.com/beego/beego/v2/core/utils"
)
// DoNothingOrm won't do anything, usually you use this to custom your mock Ormer implementation

View File

@@ -19,10 +19,10 @@ import (
"reflect"
"strings"
"github.com/astaxie/beego/core/logs"
"github.com/beego/beego/v2/core/logs"
"github.com/astaxie/beego/client/orm"
"github.com/astaxie/beego/core/bean"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/bean"
)
// DefaultValueFilterChainBuilder only works for InsertXXX method,

View File

@@ -19,7 +19,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/astaxie/beego/client/orm"
"github.com/beego/beego/v2/client/orm"
)
func TestDefaultValueFilterChainBuilder_FilterChain(t *testing.T) {

View File

@@ -20,7 +20,7 @@ import (
"github.com/opentracing/opentracing-go"
"github.com/astaxie/beego/client/orm"
"github.com/beego/beego/v2/client/orm"
)
// FilterChainBuilder provides an extension point

View File

@@ -21,7 +21,7 @@ import (
"github.com/opentracing/opentracing-go"
"github.com/astaxie/beego/client/orm"
"github.com/beego/beego/v2/client/orm"
)
func TestFilterChainBuilder_FilterChain(t *testing.T) {

View File

@@ -22,7 +22,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/astaxie/beego/client/orm"
"github.com/beego/beego/v2/client/orm"
)
// FilterChainBuilder is an extension point,
@@ -50,7 +50,7 @@ func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
"appname": builder.AppName,
},
Help: "The statics info for orm operation",
}, []string{"method", "name", "duration", "insideTx", "txName"})
}, []string{"method", "name", "insideTx", "txName"})
return func(ctx context.Context, inv *orm.Invocation) []interface{} {
startTime := time.Now()
@@ -74,12 +74,12 @@ func (builder *FilterChainBuilder) report(ctx context.Context, inv *orm.Invocati
builder.reportTxn(ctx, inv)
return
}
builder.summaryVec.WithLabelValues(inv.Method, inv.GetTableName(), strconv.Itoa(int(dur)),
strconv.FormatBool(inv.InsideTx), inv.TxName)
builder.summaryVec.WithLabelValues(inv.Method, inv.GetTableName(),
strconv.FormatBool(inv.InsideTx), inv.TxName).Observe(float64(dur))
}
func (builder *FilterChainBuilder) reportTxn(ctx context.Context, inv *orm.Invocation) {
dur := time.Now().Sub(inv.TxStartTime) / time.Millisecond
builder.summaryVec.WithLabelValues(inv.Method, inv.TxName, strconv.Itoa(int(dur)),
strconv.FormatBool(inv.InsideTx), inv.TxName)
builder.summaryVec.WithLabelValues(inv.Method, inv.TxName,
strconv.FormatBool(inv.InsideTx), inv.TxName).Observe(float64(dur))
}

View File

@@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/astaxie/beego/client/orm"
"github.com/beego/beego/v2/client/orm"
)
func TestFilterChainBuilder_FilterChain1(t *testing.T) {

View File

@@ -20,7 +20,7 @@ import (
"reflect"
"time"
"github.com/astaxie/beego/core/utils"
"github.com/beego/beego/v2/core/utils"
)
const (

View File

@@ -21,7 +21,7 @@ import (
"sync"
"testing"
"github.com/astaxie/beego/core/utils"
"github.com/beego/beego/v2/core/utils"
"github.com/stretchr/testify/assert"
)
@@ -222,7 +222,7 @@ func TestFilterOrmDecorator_InsertMulti(t *testing.T) {
}
})
bulk := []*FilterTestEntity{&FilterTestEntity{}, &FilterTestEntity{}}
bulk := []*FilterTestEntity{{}, {}}
i, err := od.InsertMulti(2, bulk)
assert.NotNil(t, err)
assert.Equal(t, "insert multi error", err.Error())

View File

@@ -15,11 +15,11 @@
package hints
import (
"github.com/astaxie/beego/core/utils"
"github.com/beego/beego/v2/core/utils"
)
const (
//query level
// query level
KeyForceIndex = iota
KeyUseIndex
KeyIgnoreIndex

View File

@@ -17,7 +17,7 @@ package migration
import (
"fmt"
"github.com/astaxie/beego/core/logs"
"github.com/beego/beego/v2/core/logs"
)
// Index struct defines the structure of Index Columns

View File

@@ -33,8 +33,8 @@ import (
"strings"
"time"
"github.com/astaxie/beego/client/orm"
"github.com/astaxie/beego/core/logs"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
)
// const the data format for the bee generate migration datatype
@@ -52,7 +52,7 @@ type Migrationer interface {
GetCreated() int64
}
//Migration defines the migrations by either SQL or DDL
// Migration defines the migrations by either SQL or DDL
type Migration struct {
sqls []string
Created string
@@ -104,7 +104,7 @@ func (m *Migration) Down() {
m.sqls = append(m.sqls, m.GetSQL())
}
//Migrate adds the SQL to the execution list
// Migrate adds the SQL to the execution list
func (m *Migration) Migrate(migrationType string) {
m.ModifyType = migrationType
m.sqls = append(m.sqls, m.GetSQL())

View File

@@ -45,7 +45,7 @@ type _modelCache struct {
done bool
}
//NewModelCacheHandler generator of _modelCache
// NewModelCacheHandler generator of _modelCache
func NewModelCacheHandler() *_modelCache {
return &_modelCache{
cache: make(map[string]*modelInfo),
@@ -113,7 +113,7 @@ func (mc *_modelCache) clean() {
mc.done = false
}
//bootstrap bootstrap for models
// bootstrap bootstrap for models
func (mc *_modelCache) bootstrap() {
mc.Lock()
defer mc.Unlock()
@@ -407,7 +407,7 @@ func (mc *_modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, m
return
}
//getDbDropSQL get database scheme drop sql queries
// getDbDropSQL get database scheme drop sql queries
func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
if len(mc.cache) == 0 {
err = errors.New("no Model found, need register your model")
@@ -422,7 +422,7 @@ func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
return queries, nil
}
//getDbCreateSQL get database scheme creation sql queries
// getDbCreateSQL get database scheme creation sql queries
func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes map[string][]dbIndex, err error) {
if len(mc.cache) == 0 {
err = errors.New("no Model found, need register your model")
@@ -467,9 +467,9 @@ func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes
column += " " + "NOT NULL"
}
//if fi.initial.String() != "" {
// if fi.initial.String() != "" {
// column += " DEFAULT " + fi.initial.String()
//}
// }
// Append attribute DEFAULT
column += getColumnDefault(fi)

View File

@@ -194,7 +194,7 @@ checkType:
}
fieldType = f.FieldType()
if fieldType&IsRelField > 0 {
err = fmt.Errorf("unsupport type custom field, please refer to https://github.com/astaxie/beego/blob/master/orm/models_fields.go#L24-L42")
err = fmt.Errorf("unsupport type custom field, please refer to https://github.com/beego/beego/v2/blob/master/orm/models_fields.go#L24-L42")
goto end
}
default:

View File

@@ -74,7 +74,7 @@ func addModelFields(mi *modelInfo, ind reflect.Value, mName string, index []int)
} else if err != nil {
break
}
//record current field index
// record current field index
fi.fieldIndex = append(fi.fieldIndex, index...)
fi.fieldIndex = append(fi.fieldIndex, i)
fi.mi = mi

View File

@@ -318,7 +318,7 @@ type Post struct {
Created time.Time `orm:"auto_now_add"`
Updated time.Time `orm:"auto_now"`
UpdatedPrecision time.Time `orm:"auto_now;type(datetime);precision(4)"`
Tags []*Tag `orm:"rel(m2m);rel_through(github.com/astaxie/beego/client/orm.PostTags)"`
Tags []*Tag `orm:"rel(m2m);rel_through(github.com/beego/beego/v2/client/orm.PostTags)"`
}
func (u *Post) TableIndex() [][]string {
@@ -376,7 +376,7 @@ type Group struct {
type Permission struct {
ID int `orm:"column(id)"`
Name string
Groups []*Group `orm:"rel(m2m);rel_through(github.com/astaxie/beego/client/orm.GroupPermissions)"`
Groups []*Group `orm:"rel(m2m);rel_through(github.com/beego/beego/v2/client/orm.GroupPermissions)"`
}
type GroupPermissions struct {
@@ -485,7 +485,7 @@ var (
usage:
go get -u github.com/astaxie/beego/client/orm
go get -u github.com/beego/beego/v2/client/orm
go get -u github.com/go-sql-driver/mysql
go get -u github.com/mattn/go-sqlite3
go get -u github.com/lib/pq
@@ -495,25 +495,25 @@ var (
mysql -u root -e 'create database orm_test;'
export ORM_DRIVER=mysql
export ORM_SOURCE="root:@/orm_test?charset=utf8"
go test -v github.com/astaxie/beego/client/orm
go test -v github.com/beego/beego/v2/client/orm
#### Sqlite3
export ORM_DRIVER=sqlite3
export ORM_SOURCE='file:memory_test?mode=memory'
go test -v github.com/astaxie/beego/client/orm
go test -v github.com/beego/beego/v2/client/orm
#### PostgreSQL
psql -c 'create database orm_test;' -U postgres
export ORM_DRIVER=postgres
export ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
go test -v github.com/astaxie/beego/client/orm
go test -v github.com/beego/beego/v2/client/orm
#### TiDB
export ORM_DRIVER=tidb
export ORM_SOURCE='memory://test/test'
go test -v github.com/astaxie/beego/pgk/orm
go test -v github.com/beego/beego/v2/pgk/orm
`
)

View File

@@ -21,7 +21,7 @@
//
// import (
// "fmt"
// "github.com/astaxie/beego/client/orm"
// "github.com/beego/beego/v2/client/orm"
// _ "github.com/go-sql-driver/mysql" // import your used driver
// )
//
@@ -63,10 +63,10 @@ import (
"reflect"
"time"
"github.com/astaxie/beego/client/orm/hints"
"github.com/astaxie/beego/core/utils"
"github.com/beego/beego/v2/client/orm/hints"
"github.com/beego/beego/v2/core/utils"
"github.com/astaxie/beego/core/logs"
"github.com/beego/beego/v2/core/logs"
)
// DebugQueries define the debug

View File

@@ -77,10 +77,13 @@ func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
// AndCond combine a condition to current condition
func (c *Condition) AndCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {
panic(fmt.Errorf("<Condition.AndCond> cannot use self as sub cond"))
}
c = c.clone()
if cond != nil {
c.params = append(c.params, condValue{cond: cond, isCond: true})
}
@@ -150,5 +153,8 @@ func (c *Condition) IsEmpty() bool {
// clone clone a condition
func (c Condition) clone() *Condition {
params := make([]condValue, len(c.params))
copy(params, c.params)
c.params = params
return &c
}

View File

@@ -29,7 +29,7 @@ type Log struct {
*log.Logger
}
//costomer log func
// costomer log func
var LogFunc func(query map[string]interface{})
// NewLog set io.Writer to create a Logger.

View File

@@ -17,8 +17,8 @@ package orm
import (
"context"
"fmt"
"github.com/astaxie/beego/client/orm/hints"
"github.com/astaxie/beego/client/orm/clauses/order_clause"
"github.com/astaxie/beego/v2/client/orm/hints"
"github.com/astaxie/beego/v2/client/orm/clauses/order_clause"
)
type colValue struct {

View File

@@ -181,6 +181,12 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
if err == nil {
ind.Set(reflect.ValueOf(t))
}
} else if len(str) >= 8 {
str = str[:8]
t, err := time.ParseInLocation(formatTime, str, DefaultTimeLoc)
if err == nil {
ind.Set(reflect.ValueOf(t))
}
}
}
case sql.NullString, sql.NullInt64, sql.NullFloat64, sql.NullBool:

View File

@@ -32,7 +32,7 @@ import (
"testing"
"time"
"github.com/astaxie/beego/client/orm/hints"
"github.com/beego/beego/v2/client/orm/hints"
"github.com/stretchr/testify/assert"
)
@@ -1780,6 +1780,10 @@ func TestRawQueryRow(t *testing.T) {
throwFail(t, AssertIs(id, 1))
break
case "time":
v = v.(time.Time).In(DefaultTimeLoc)
value := dataValues[col].(time.Time).In(DefaultTimeLoc)
assert.True(t, v.(time.Time).Sub(value) <= time.Second)
break
case "date":
case "datetime":
v = v.(time.Time).In(DefaultTimeLoc)
@@ -1807,12 +1811,12 @@ func TestRawQueryRow(t *testing.T) {
throwFail(t, AssertIs(*status, 3))
throwFail(t, AssertIs(pid, nil))
type Embeded struct {
type Embedded struct {
Email string
}
type queryRowNoModelTest struct {
Id int
EmbedField Embeded
EmbedField Embedded
}
cols = []string{
@@ -2702,3 +2706,48 @@ func TestPSQueryBuilder(t *testing.T) {
throwFailNow(t, AssertIs(l[0].UserName, "astaxie"))
throwFailNow(t, AssertIs(l[0].Age, 30))
}
func TestCondition(t *testing.T) {
// test Condition whether to include yourself
cond := NewCondition()
cond = cond.AndCond(cond.Or("ID", 1))
cond = cond.AndCond(cond.Or("ID", 2))
cond = cond.AndCond(cond.Or("ID", 3))
cond = cond.AndCond(cond.Or("ID", 4))
cycleFlag := false
var hasCycle func(*Condition)
hasCycle = func(c *Condition) {
if nil == c || cycleFlag {
return
}
condPointMap := make(map[string]bool)
condPointMap[fmt.Sprintf("%p", c)] = true
for _, p := range c.params {
if p.isCond {
adr := fmt.Sprintf("%p", p.cond)
if condPointMap[adr] {
// self as sub cond was cycle
cycleFlag = true
break
}
condPointMap[adr] = true
}
}
if cycleFlag {
return
}
for _, p := range c.params {
if p.isCond {
// check next cond
hasCycle(p.cond)
}
}
return
}
hasCycle(cond)
// cycleFlag was true,meaning use self as sub cond
throwFail(t, AssertIs(!cycleFlag, true))
return
}

View File

@@ -21,7 +21,7 @@ import (
"reflect"
"time"
"github.com/astaxie/beego/core/utils"
"github.com/beego/beego/v2/core/utils"
)
// TableNaming is usually used by model
@@ -96,13 +96,13 @@ type Fielder interface {
}
type TxBeginner interface {
//self control transaction
// self control transaction
Begin() (TxOrmer, error)
BeginWithCtx(ctx context.Context) (TxOrmer, error)
BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error)
BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error)
//closure control transaction
// closure control transaction
DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error
DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error
DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
@@ -114,7 +114,7 @@ type TxCommitter interface {
Rollback() error
}
//Data Manipulation Language
// Data Manipulation Language
type DML interface {
// insert model data to database
// for example:

View File

@@ -49,12 +49,12 @@ func (f *StrTo) Set(v string) {
// Clear string
func (f *StrTo) Clear() {
*f = StrTo(0x1E)
*f = StrTo(rune(0x1E))
}
// Exist check string exist
func (f StrTo) Exist() bool {
return string(f) != string(0x1E)
return string(f) != string(rune(0x1E))
}
// Bool string to bool