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 {
case maxAge > 0:
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")
}
}

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 {
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++
}

View File

@ -75,7 +75,7 @@ func registerModel(PrefixOrSuffix string, model interface{}, isPrefix bool) {
}
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)
}

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 {
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

View File

@ -493,19 +493,33 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
}
}
} else {
for i := 0; i < ind.NumField(); i++ {
f := ind.Field(i)
fe := ind.Type().Field(i)
_, 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)
// define recursive function
var recursiveSetField func(rv reflect.Value)
recursiveSetField = func(rv reflect.Value) {
for i := 0; i < rv.NumField(); i++ {
f := rv.Field(i)
fe := rv.Type().Field(i)
// check if the field is a Struct
// recursive the Struct type
if fe.Type.Kind() == reflect.Struct {
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 {

View File

@ -1661,6 +1661,13 @@ func TestRawQueryRow(t *testing.T) {
throwFail(t, AssertIs(pid, nil))
}
// user_profile table
type userProfile struct {
User
Age int
Money float64
}
func TestQueryRows(t *testing.T) {
Q := dDbBaser.TableQuote()
@ -1731,6 +1738,19 @@ func TestQueryRows(t *testing.T) {
throwFailNow(t, AssertIs(usernames[1], "astaxie"))
throwFailNow(t, AssertIs(ids[2], 4))
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) {

View File

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

View File

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

View File

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

View File

@ -175,10 +175,10 @@ func TestAlphaNumeric(t *testing.T) {
func TestMatch(t *testing.T) {
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")
}
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")
}
}
@ -186,10 +186,10 @@ func TestMatch(t *testing.T) {
func TestNoMatch(t *testing.T) {
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")
}
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")
}
}

View File

@ -145,7 +145,7 @@ func (r Required) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default error message
func (r Required) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Required"])
return MessageTmpls["Required"]
}
// GetKey return the r.Key
@ -364,7 +364,7 @@ func (a Alpha) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Length error message
func (a Alpha) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Alpha"])
return MessageTmpls["Alpha"]
}
// GetKey return the m.Key
@ -397,7 +397,7 @@ func (n Numeric) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Length error message
func (n Numeric) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Numeric"])
return MessageTmpls["Numeric"]
}
// GetKey return the n.Key
@ -430,7 +430,7 @@ func (a AlphaNumeric) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Length error message
func (a AlphaNumeric) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["AlphaNumeric"])
return MessageTmpls["AlphaNumeric"]
}
// GetKey return the a.Key
@ -495,7 +495,7 @@ func (n NoMatch) GetLimitValue() interface{} {
return n.Regexp.String()
}
var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]")
var alphaDashPattern = regexp.MustCompile(`[^\d\w-_]`)
// AlphaDash check not Alpha
type AlphaDash struct {
@ -505,7 +505,7 @@ type AlphaDash struct {
// DefaultMessage return the default AlphaDash error message
func (a AlphaDash) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["AlphaDash"])
return MessageTmpls["AlphaDash"]
}
// GetKey return the n.Key
@ -518,7 +518,7 @@ func (a AlphaDash) GetLimitValue() interface{} {
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
type Email struct {
@ -528,7 +528,7 @@ type Email struct {
// DefaultMessage return the default Email error message
func (e Email) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Email"])
return MessageTmpls["Email"]
}
// GetKey return the n.Key
@ -541,7 +541,7 @@ func (e Email) GetLimitValue() interface{} {
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
type IP struct {
@ -551,7 +551,7 @@ type IP struct {
// DefaultMessage return the default IP error message
func (i IP) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["IP"])
return MessageTmpls["IP"]
}
// GetKey return the i.Key
@ -564,7 +564,7 @@ func (i IP) GetLimitValue() interface{} {
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
type Base64 struct {
@ -574,7 +574,7 @@ type Base64 struct {
// DefaultMessage return the default Base64 error message
func (b Base64) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Base64"])
return MessageTmpls["Base64"]
}
// GetKey return the b.Key
@ -588,7 +588,7 @@ func (b Base64) GetLimitValue() interface{} {
}
// 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
type Mobile struct {
@ -598,7 +598,7 @@ type Mobile struct {
// DefaultMessage return the default Mobile error message
func (m Mobile) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Mobile"])
return MessageTmpls["Mobile"]
}
// GetKey return the m.Key
@ -612,7 +612,7 @@ func (m Mobile) GetLimitValue() interface{} {
}
// 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
type Tel struct {
@ -622,7 +622,7 @@ type Tel struct {
// DefaultMessage return the default Tel error message
func (t Tel) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Tel"])
return MessageTmpls["Tel"]
}
// GetKey return the t.Key
@ -649,7 +649,7 @@ func (p Phone) IsSatisfied(obj interface{}) bool {
// DefaultMessage return the default Phone error message
func (p Phone) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["Phone"])
return MessageTmpls["Phone"]
}
// GetKey return the p.Key
@ -663,7 +663,7 @@ func (p Phone) GetLimitValue() interface{} {
}
// 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
type ZipCode struct {
@ -673,7 +673,7 @@ type ZipCode struct {
// DefaultMessage return the default Zip error message
func (z ZipCode) DefaultMessage() string {
return fmt.Sprint(MessageTmpls["ZipCode"])
return MessageTmpls["ZipCode"]
}
// GetKey return the z.Key