1
0
mirror of https://github.com/astaxie/beego.git synced 2024-06-13 16:23:32 +00:00

Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Eyal Post 2017-05-17 20:02:40 +03:00
commit d54cd4fa5f
11 changed files with 106 additions and 67 deletions

View File

@ -105,7 +105,7 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface
switch { switch {
case maxAge > 0: case maxAge > 0:
fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge) fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge)
case maxAge <= 0: case maxAge < 0:
fmt.Fprintf(&b, "; Max-Age=0") fmt.Fprintf(&b, "; Max-Age=0")
} }
} }

View File

@ -833,7 +833,11 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
if err := rs.Scan(&ref); err != nil { if err := rs.Scan(&ref); err != nil {
return 0, err return 0, err
} }
args = append(args, reflect.ValueOf(ref).Interface()) pkValue, err := d.convertValueFromDB(mi.fields.pk, reflect.ValueOf(ref).Interface(), tz)
if err != nil {
return 0, err
}
args = append(args, pkValue)
cnt++ cnt++
} }

View File

@ -75,7 +75,7 @@ func registerModel(PrefixOrSuffix string, model interface{}, isPrefix bool) {
} }
if mi.fields.pk == nil { if mi.fields.pk == nil {
fmt.Printf("<orm.RegisterModel> `%s` need a primary key field, default use 'id' if not set\n", name) fmt.Printf("<orm.RegisterModel> `%s` needs a primary key field, default is to use 'id' if not set\n", name)
os.Exit(2) os.Exit(2)
} }

View File

@ -107,7 +107,7 @@ func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect
if mi, ok := modelCache.getByFullName(name); ok { if mi, ok := modelCache.getByFullName(name); ok {
return mi, ind return mi, ind
} }
panic(fmt.Errorf("<Ormer> table: `%s` not found, maybe not RegisterModel", name)) panic(fmt.Errorf("<Ormer> table: `%s` not found, make sure it was registered with `RegisterModel()`", name))
} }
// get field info from model info by given field name // get field info from model info by given field name

View File

@ -493,19 +493,33 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
} }
} }
} else { } else {
for i := 0; i < ind.NumField(); i++ { // define recursive function
f := ind.Field(i) var recursiveSetField func(rv reflect.Value)
fe := ind.Type().Field(i) recursiveSetField = func(rv reflect.Value) {
_, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) for i := 0; i < rv.NumField(); i++ {
var col string f := rv.Field(i)
if col = tags["column"]; col == "" { fe := rv.Type().Field(i)
col = snakeString(fe.Name)
} // check if the field is a Struct
if v, ok := columnsMp[col]; ok { // recursive the Struct type
value := reflect.ValueOf(v).Elem().Interface() if fe.Type.Kind() == reflect.Struct {
o.setFieldValue(f, value) recursiveSetField(f)
}
_, tags := parseStructTag(fe.Tag.Get(defaultStructTagName))
var col string
if col = tags["column"]; col == "" {
col = snakeString(fe.Name)
}
if v, ok := columnsMp[col]; ok {
value := reflect.ValueOf(v).Elem().Interface()
o.setFieldValue(f, value)
}
} }
} }
// init call the recursive function
recursiveSetField(ind)
} }
if eTyps[0].Kind() == reflect.Ptr { if eTyps[0].Kind() == reflect.Ptr {

View File

@ -1661,6 +1661,13 @@ func TestRawQueryRow(t *testing.T) {
throwFail(t, AssertIs(pid, nil)) throwFail(t, AssertIs(pid, nil))
} }
// user_profile table
type userProfile struct {
User
Age int
Money float64
}
func TestQueryRows(t *testing.T) { func TestQueryRows(t *testing.T) {
Q := dDbBaser.TableQuote() Q := dDbBaser.TableQuote()
@ -1731,6 +1738,19 @@ func TestQueryRows(t *testing.T) {
throwFailNow(t, AssertIs(usernames[1], "astaxie")) throwFailNow(t, AssertIs(usernames[1], "astaxie"))
throwFailNow(t, AssertIs(ids[2], 4)) throwFailNow(t, AssertIs(ids[2], 4))
throwFailNow(t, AssertIs(usernames[2], "nobody")) throwFailNow(t, AssertIs(usernames[2], "nobody"))
//test query rows by nested struct
var l []userProfile
query = fmt.Sprintf("SELECT * FROM %suser_profile%s LEFT JOIN %suser%s ON %suser_profile%s.%sid%s = %suser%s.%sid%s", Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q)
num, err = dORM.Raw(query).QueryRows(&l)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 2))
throwFailNow(t, AssertIs(len(l), 2))
throwFailNow(t, AssertIs(l[0].UserName, "slene"))
throwFailNow(t, AssertIs(l[0].Age, 28))
throwFailNow(t, AssertIs(l[1].UserName, "astaxie"))
throwFailNow(t, AssertIs(l[1].Age, 30))
} }
func TestRawValues(t *testing.T) { func TestRawValues(t *testing.T) {

View File

@ -179,7 +179,7 @@ func (rp *Provider) SessionRead(sid string) (session.Store, error) {
var kv map[interface{}]interface{} var kv map[interface{}]interface{}
kvs, err := redis.String(c.Do("GET", sid)) kvs, err := redis.String(c.Do("GET", sid))
if err != redis.ErrNil { if err != nil && err != redis.ErrNil {
return nil, err return nil, err
} }
if len(kvs) == 0 { if len(kvs) == 0 {

View File

@ -22,19 +22,19 @@ package swagger
// Swagger list the resource // Swagger list the resource
type Swagger struct { type Swagger struct {
SwaggerVersion string `json:"swagger,omitempty" yaml:"swagger,omitempty"` SwaggerVersion string `json:"swagger,omitempty" yaml:"swagger,omitempty"`
Infos Information `json:"info" yaml:"info"` Infos Information `json:"info" yaml:"info"`
Host string `json:"host,omitempty" yaml:"host,omitempty"` Host string `json:"host,omitempty" yaml:"host,omitempty"`
BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"` BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"`
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"` Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"` Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"` Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
Paths map[string]*Item `json:"paths" yaml:"paths"` Paths map[string]*Item `json:"paths" yaml:"paths"`
Definitions map[string]Schema `json:"definitions,omitempty" yaml:"definitions,omitempty"` Definitions map[string]Schema `json:"definitions,omitempty" yaml:"definitions,omitempty"`
SecurityDefinitions map[string]Security `json:"securityDefinitions,omitempty" yaml:"securityDefinitions,omitempty"` SecurityDefinitions map[string]Security `json:"securityDefinitions,omitempty" yaml:"securityDefinitions,omitempty"`
Security map[string][]string `json:"security,omitempty" yaml:"security,omitempty"` Security []map[string][]string `json:"security,omitempty" yaml:"security,omitempty"`
Tags []Tag `json:"tags,omitempty" yaml:"tags,omitempty"` Tags []Tag `json:"tags,omitempty" yaml:"tags,omitempty"`
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"` ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
} }
// Information Provides metadata about the API. The metadata can be used by the clients if needed. // Information Provides metadata about the API. The metadata can be used by the clients if needed.
@ -75,16 +75,17 @@ type Item struct {
// Operation Describes a single API operation on a path. // Operation Describes a single API operation on a path.
type Operation struct { type Operation struct {
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"` Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"` Description string `json:"description,omitempty" yaml:"description,omitempty"`
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"` OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"` Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"` Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"` Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
Parameters []Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"` Parameters []Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
Responses map[string]Response `json:"responses,omitempty" yaml:"responses,omitempty"` Responses map[string]Response `json:"responses,omitempty" yaml:"responses,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"` Security []map[string][]string `json:"security,omitempty" yaml:"security,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
} }
// Parameter Describes a single operation parameter. // Parameter Describes a single operation parameter.

View File

@ -53,21 +53,21 @@ func Substr(s string, start, length int) string {
// HTML2str returns escaping text convert from html. // HTML2str returns escaping text convert from html.
func HTML2str(html string) string { func HTML2str(html string) string {
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>") re, _ := regexp.Compile(`\<[\S\s]+?\>`)
html = re.ReplaceAllStringFunc(html, strings.ToLower) html = re.ReplaceAllStringFunc(html, strings.ToLower)
//remove STYLE //remove STYLE
re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>") re, _ = regexp.Compile(`\<style[\S\s]+?\</style\>`)
html = re.ReplaceAllString(html, "") html = re.ReplaceAllString(html, "")
//remove SCRIPT //remove SCRIPT
re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>") re, _ = regexp.Compile(`\<script[\S\s]+?\</script\>`)
html = re.ReplaceAllString(html, "") html = re.ReplaceAllString(html, "")
re, _ = regexp.Compile("\\<[\\S\\s]+?\\>") re, _ = regexp.Compile(`\<[\S\s]+?\>`)
html = re.ReplaceAllString(html, "\n") html = re.ReplaceAllString(html, "\n")
re, _ = regexp.Compile("\\s{2,}") re, _ = regexp.Compile(`\s{2,}`)
html = re.ReplaceAllString(html, "\n") html = re.ReplaceAllString(html, "\n")
return strings.TrimSpace(html) return strings.TrimSpace(html)

View File

@ -175,10 +175,10 @@ func TestAlphaNumeric(t *testing.T) {
func TestMatch(t *testing.T) { func TestMatch(t *testing.T) {
valid := Validation{} valid := Validation{}
if valid.Match("suchuangji@gmail", regexp.MustCompile("^\\w+@\\w+\\.\\w+$"), "match").Ok { if valid.Match("suchuangji@gmail", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok {
t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be false") t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be false")
} }
if !valid.Match("suchuangji@gmail.com", regexp.MustCompile("^\\w+@\\w+\\.\\w+$"), "match").Ok { if !valid.Match("suchuangji@gmail.com", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok {
t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true") t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true")
} }
} }
@ -186,10 +186,10 @@ func TestMatch(t *testing.T) {
func TestNoMatch(t *testing.T) { func TestNoMatch(t *testing.T) {
valid := Validation{} valid := Validation{}
if valid.NoMatch("123@gmail", regexp.MustCompile("[^\\w\\d]"), "nomatch").Ok { if valid.NoMatch("123@gmail", regexp.MustCompile(`[^\w\d]`), "nomatch").Ok {
t.Error("\"123@gmail\" not match \"[^\\w\\d]\" should be false") t.Error("\"123@gmail\" not match \"[^\\w\\d]\" should be false")
} }
if !valid.NoMatch("123gmail", regexp.MustCompile("[^\\w\\d]"), "match").Ok { if !valid.NoMatch("123gmail", regexp.MustCompile(`[^\w\d]`), "match").Ok {
t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true") t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true")
} }
} }

View File

@ -145,7 +145,7 @@ func (r Required) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default error message // DefaultMessage return the default error message
func (r Required) DefaultMessage() string { func (r Required) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Required"]) return MessageTmpls["Required"]
} }
// GetKey return the r.Key // GetKey return the r.Key
@ -364,7 +364,7 @@ func (a Alpha) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Length error message // DefaultMessage return the default Length error message
func (a Alpha) DefaultMessage() string { func (a Alpha) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Alpha"]) return MessageTmpls["Alpha"]
} }
// GetKey return the m.Key // GetKey return the m.Key
@ -397,7 +397,7 @@ func (n Numeric) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Length error message // DefaultMessage return the default Length error message
func (n Numeric) DefaultMessage() string { func (n Numeric) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Numeric"]) return MessageTmpls["Numeric"]
} }
// GetKey return the n.Key // GetKey return the n.Key
@ -430,7 +430,7 @@ func (a AlphaNumeric) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Length error message // DefaultMessage return the default Length error message
func (a AlphaNumeric) DefaultMessage() string { func (a AlphaNumeric) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["AlphaNumeric"]) return MessageTmpls["AlphaNumeric"]
} }
// GetKey return the a.Key // GetKey return the a.Key
@ -495,7 +495,7 @@ func (n NoMatch) GetLimitValue() interface{} {
return n.Regexp.String() return n.Regexp.String()
} }
var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]") var alphaDashPattern = regexp.MustCompile(`[^\d\w-_]`)
// AlphaDash check not Alpha // AlphaDash check not Alpha
type AlphaDash struct { type AlphaDash struct {
@ -505,7 +505,7 @@ type AlphaDash struct {
// DefaultMessage return the default AlphaDash error message // DefaultMessage return the default AlphaDash error message
func (a AlphaDash) DefaultMessage() string { func (a AlphaDash) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["AlphaDash"]) return MessageTmpls["AlphaDash"]
} }
// GetKey return the n.Key // GetKey return the n.Key
@ -518,7 +518,7 @@ func (a AlphaDash) GetLimitValue() interface{} {
return nil return nil
} }
var emailPattern = regexp.MustCompile("^[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?$") var emailPattern = regexp.MustCompile(`^[\w!#$%&'*+/=?^_` + "`" + `{|}~-]+(?:\.[\w!#$%&'*+/=?^_` + "`" + `{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[a-zA-Z0-9](?:[\w-]*[\w])?$`)
// Email check struct // Email check struct
type Email struct { type Email struct {
@ -528,7 +528,7 @@ type Email struct {
// DefaultMessage return the default Email error message // DefaultMessage return the default Email error message
func (e Email) DefaultMessage() string { func (e Email) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Email"]) return MessageTmpls["Email"]
} }
// GetKey return the n.Key // GetKey return the n.Key
@ -541,7 +541,7 @@ func (e Email) GetLimitValue() interface{} {
return nil return nil
} }
var ipPattern = regexp.MustCompile("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$") var ipPattern = regexp.MustCompile(`^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$`)
// IP check struct // IP check struct
type IP struct { type IP struct {
@ -551,7 +551,7 @@ type IP struct {
// DefaultMessage return the default IP error message // DefaultMessage return the default IP error message
func (i IP) DefaultMessage() string { func (i IP) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["IP"]) return MessageTmpls["IP"]
} }
// GetKey return the i.Key // GetKey return the i.Key
@ -564,7 +564,7 @@ func (i IP) GetLimitValue() interface{} {
return nil return nil
} }
var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$") var base64Pattern = regexp.MustCompile(`^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$`)
// Base64 check struct // Base64 check struct
type Base64 struct { type Base64 struct {
@ -574,7 +574,7 @@ type Base64 struct {
// DefaultMessage return the default Base64 error message // DefaultMessage return the default Base64 error message
func (b Base64) DefaultMessage() string { func (b Base64) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Base64"]) return MessageTmpls["Base64"]
} }
// GetKey return the b.Key // GetKey return the b.Key
@ -588,7 +588,7 @@ func (b Base64) GetLimitValue() interface{} {
} }
// just for chinese mobile phone number // just for chinese mobile phone number
var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][06789]|[4][579]))\\d{8}$") var mobilePattern = regexp.MustCompile(`^((\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][06789]|[4][579]))\d{8}$`)
// Mobile check struct // Mobile check struct
type Mobile struct { type Mobile struct {
@ -598,7 +598,7 @@ type Mobile struct {
// DefaultMessage return the default Mobile error message // DefaultMessage return the default Mobile error message
func (m Mobile) DefaultMessage() string { func (m Mobile) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Mobile"]) return MessageTmpls["Mobile"]
} }
// GetKey return the m.Key // GetKey return the m.Key
@ -612,7 +612,7 @@ func (m Mobile) GetLimitValue() interface{} {
} }
// just for chinese telephone number // just for chinese telephone number
var telPattern = regexp.MustCompile("^(0\\d{2,3}(\\-)?)?\\d{7,8}$") var telPattern = regexp.MustCompile(`^(0\d{2,3}(\-)?)?\d{7,8}$`)
// Tel check telephone struct // Tel check telephone struct
type Tel struct { type Tel struct {
@ -622,7 +622,7 @@ type Tel struct {
// DefaultMessage return the default Tel error message // DefaultMessage return the default Tel error message
func (t Tel) DefaultMessage() string { func (t Tel) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Tel"]) return MessageTmpls["Tel"]
} }
// GetKey return the t.Key // GetKey return the t.Key
@ -649,7 +649,7 @@ func (p Phone) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Phone error message // DefaultMessage return the default Phone error message
func (p Phone) DefaultMessage() string { func (p Phone) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Phone"]) return MessageTmpls["Phone"]
} }
// GetKey return the p.Key // GetKey return the p.Key
@ -663,7 +663,7 @@ func (p Phone) GetLimitValue() interface{} {
} }
// just for chinese zipcode // just for chinese zipcode
var zipCodePattern = regexp.MustCompile("^[1-9]\\d{5}$") var zipCodePattern = regexp.MustCompile(`^[1-9]\d{5}$`)
// ZipCode check the zip struct // ZipCode check the zip struct
type ZipCode struct { type ZipCode struct {
@ -673,7 +673,7 @@ type ZipCode struct {
// DefaultMessage return the default Zip error message // DefaultMessage return the default Zip error message
func (z ZipCode) DefaultMessage() string { func (z ZipCode) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["ZipCode"]) return MessageTmpls["ZipCode"]
} }
// GetKey return the z.Key // GetKey return the z.Key