Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
f6c508f1
Commit
f6c508f1
authored
Dec 21, 2015
by
fud
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of
https://github.com/astaxie/beego
into develop
parents
f9138c5a
130ce7eb
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
287 additions
and
40 deletions
+287
-40
acceptencoder.go
context/acceptencoder.go
+6
-1
types.go
orm/types.go
+261
-31
cors_test.go
plugins/cors/cors_test.go
+2
-2
staticfile_test.go
staticfile_test.go
+2
-2
tree.go
tree.go
+16
-4
No files found.
context/acceptencoder.go
View file @
f6c508f1
...
...
@@ -18,6 +18,7 @@ import (
"bytes"
"compress/flate"
"compress/gzip"
"compress/zlib"
"io"
"net/http"
"os"
...
...
@@ -33,7 +34,11 @@ type acceptEncoder struct {
var
(
noneCompressEncoder
=
acceptEncoder
{
""
,
func
(
wr
io
.
Writer
,
level
int
)
(
io
.
Writer
,
error
)
{
return
wr
,
nil
}}
gzipCompressEncoder
=
acceptEncoder
{
"gzip"
,
func
(
wr
io
.
Writer
,
level
int
)
(
io
.
Writer
,
error
)
{
return
gzip
.
NewWriterLevel
(
wr
,
level
)
}}
deflateCompressEncoder
=
acceptEncoder
{
"deflate"
,
func
(
wr
io
.
Writer
,
level
int
)
(
io
.
Writer
,
error
)
{
return
flate
.
NewWriter
(
wr
,
level
)
}}
//according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed
//deflate
//The "zlib" format defined in RFC 1950 [31] in combination with
//the "deflate" compression mechanism described in RFC 1951 [29].
deflateCompressEncoder
=
acceptEncoder
{
"deflate"
,
func
(
wr
io
.
Writer
,
level
int
)
(
io
.
Writer
,
error
)
{
return
zlib
.
NewWriterLevel
(
wr
,
level
)
}}
)
var
(
...
...
orm/types.go
View file @
f6c508f1
...
...
@@ -36,20 +36,77 @@ type Fielder interface {
// Ormer define the orm interface
type
Ormer
interface
{
Read
(
interface
{},
...
string
)
error
ReadOrCreate
(
interface
{},
string
,
...
string
)
(
bool
,
int64
,
error
)
// read data to model
// for example:
// this will find User by Id field
// u = &User{Id: user.Id}
// err = Ormer.Read(u)
// this will find User by UserName field
// u = &User{UserName: "astaxie", Password: "pass"}
// err = Ormer.Read(u, "UserName")
Read
(
md
interface
{},
cols
...
string
)
error
// Try to read a row from the database, or insert one if it doesn't exist
ReadOrCreate
(
md
interface
{},
col1
string
,
cols
...
string
)
(
bool
,
int64
,
error
)
// insert model data to database
// for example:
// user := new(User)
// id, err = Ormer.Insert(user)
// user must a pointer and Insert will set user's pk field
Insert
(
interface
{})
(
int64
,
error
)
InsertMulti
(
int
,
interface
{})
(
int64
,
error
)
Update
(
interface
{},
...
string
)
(
int64
,
error
)
Delete
(
interface
{})
(
int64
,
error
)
LoadRelated
(
interface
{},
string
,
...
interface
{})
(
int64
,
error
)
QueryM2M
(
interface
{},
string
)
QueryM2Mer
QueryTable
(
interface
{})
QuerySeter
Using
(
string
)
error
// insert some models to database
InsertMulti
(
bulk
int
,
mds
interface
{})
(
int64
,
error
)
// update model to database.
// cols set the columns those want to update.
// find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns
// for example:
// user := User{Id: 2}
// user.Langs = append(user.Langs, "zh-CN", "en-US")
// user.Extra.Name = "beego"
// user.Extra.Data = "orm"
// num, err = Ormer.Update(&user, "Langs", "Extra")
Update
(
md
interface
{},
cols
...
string
)
(
int64
,
error
)
// delete model in database
Delete
(
md
interface
{})
(
int64
,
error
)
// load related models to md model.
// args are limit, offset int and order string.
//
// example:
// Ormer.LoadRelated(post,"Tags")
// for _,tag := range post.Tags{...}
//args[0] bool true useDefaultRelsDepth ; false depth 0
//args[0] int loadRelationDepth
//args[1] int limit default limit 1000
//args[2] int offset default offset 0
//args[3] string order for example : "-Id"
// make sure the relation is defined in model struct tags.
LoadRelated
(
md
interface
{},
name
string
,
args
...
interface
{})
(
int64
,
error
)
// create a models to models queryer
// for example:
// post := Post{Id: 4}
// m2m := Ormer.QueryM2M(&post, "Tags")
QueryM2M
(
md
interface
{},
name
string
)
QueryM2Mer
// return a QuerySeter for table operations.
// table name can be string or struct.
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
QueryTable
(
ptrStructOrTableName
interface
{})
QuerySeter
// switch to another registered database driver by given name.
Using
(
name
string
)
error
// begin transaction
// for example:
// o := NewOrm()
// err := o.Begin()
// ...
// err = o.Rollback()
Begin
()
error
// commit transaction
Commit
()
error
// rollback transaction
Rollback
()
error
Raw
(
string
,
...
interface
{})
RawSeter
// return a raw query seter for raw sql string.
// for example:
// ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec()
// // update user testing's name to slene
Raw
(
query
string
,
args
...
interface
{})
RawSeter
Driver
()
Driver
}
...
...
@@ -61,38 +118,164 @@ type Inserter interface {
// QuerySeter query seter
type
QuerySeter
interface
{
// add condition expression to QuerySeter.
// for example:
// filter by UserName == 'slene'
// qs.Filter("UserName", "slene")
// sql : left outer join profile on t0.id1==t1.id2 where t1.age == 28
// Filter("profile__Age", 28)
// // time compare
// qs.Filter("created", time.Now())
Filter
(
string
,
...
interface
{})
QuerySeter
// add NOT condition to querySeter.
// have the same usage as Filter
Exclude
(
string
,
...
interface
{})
QuerySeter
// set condition to QuerySeter.
// sql's where condition
// cond := orm.NewCondition()
// cond1 := cond.And("profile__isnull", false).AndNot("status__in", 1).Or("profile__age__gt", 2000)
// //sql-> WHERE T0.`profile_id` IS NOT NULL AND NOT T0.`Status` IN (?) OR T1.`age` > 2000
// num, err := qs.SetCond(cond1).Count()
SetCond
(
*
Condition
)
QuerySeter
Limit
(
interface
{},
...
interface
{})
QuerySeter
Offset
(
interface
{})
QuerySeter
GroupBy
(
...
string
)
QuerySeter
OrderBy
(
...
string
)
QuerySeter
Distinct
()
QuerySeter
RelatedSel
(
...
interface
{})
QuerySeter
// add LIMIT value.
// args[0] means offset, e.g. LIMIT num,offset.
// if Limit <= 0 then Limit will be set to default limit ,eg 1000
// if QuerySeter doesn't call Limit, the sql's Limit will be set to default limit, eg 1000
// for example:
// qs.Limit(10, 2)
// // sql-> limit 10 offset 2
Limit
(
limit
interface
{},
args
...
interface
{})
QuerySeter
// add OFFSET value
// same as Limit function's args[0]
Offset
(
offset
interface
{})
QuerySeter
// add ORDER expression.
// "column" means ASC, "-column" means DESC.
// for example:
// qs.OrderBy("-status")
OrderBy
(
exprs
...
string
)
QuerySeter
// set relation model to query together.
// it will query relation models and assign to parent model.
// for example:
// // will load all related fields use left join .
// qs.RelatedSel().One(&user)
// // will load related field only profile
// qs.RelatedSel("profile").One(&user)
// user.Profile.Age = 32
RelatedSel
(
params
...
interface
{})
QuerySeter
// return QuerySeter execution result number
// for example:
// num, err = qs.Filter("profile__age__gt", 28).Count()
Count
()
(
int64
,
error
)
// check result empty or not after QuerySeter executed
// the same as QuerySeter.Count > 0
Exist
()
bool
Update
(
Params
)
(
int64
,
error
)
// execute update with parameters
// for example:
// num, err = qs.Filter("user_name", "slene").Update(Params{
// "Nums": ColValue(Col_Minus, 50),
// }) // user slene's Nums will minus 50
// num, err = qs.Filter("UserName", "slene").Update(Params{
// "user_name": "slene2"
// }) // user slene's name will change to slene2
Update
(
values
Params
)
(
int64
,
error
)
// delete from table
//for example:
// num ,err = qs.Filter("user_name__in", "testing1", "testing2").Delete()
// //delete two user who's name is testing1 or testing2
Delete
()
(
int64
,
error
)
// return a insert queryer.
// it can be used in times.
// example:
// i,err := sq.PrepareInsert()
// num, err = i.Insert(&user1) // user table will add one record user1 at once
// num, err = i.Insert(&user2) // user table will add one record user2 at once
// err = i.Close() //don't forget call Close
PrepareInsert
()
(
Inserter
,
error
)
All
(
interface
{},
...
string
)
(
int64
,
error
)
One
(
interface
{},
...
string
)
error
Values
(
*
[]
Params
,
...
string
)
(
int64
,
error
)
ValuesList
(
*
[]
ParamsList
,
...
string
)
(
int64
,
error
)
ValuesFlat
(
*
ParamsList
,
string
)
(
int64
,
error
)
RowsToMap
(
*
Params
,
string
,
string
)
(
int64
,
error
)
RowsToStruct
(
interface
{},
string
,
string
)
(
int64
,
error
)
// query all data and map to containers.
// cols means the columns when querying.
// for example:
// var users []*User
// qs.All(&users) // users[0],users[1],users[2] ...
All
(
container
interface
{},
cols
...
string
)
(
int64
,
error
)
// query one row data and map to containers.
// cols means the columns when querying.
// for example:
// var user User
// qs.One(&user) //user.UserName == "slene"
One
(
container
interface
{},
cols
...
string
)
error
// query all data and map to []map[string]interface.
// expres means condition expression.
// it converts data to []map[column]value.
// for example:
// var maps []Params
// qs.Values(&maps) //maps[0]["UserName"]=="slene"
Values
(
results
*
[]
Params
,
exprs
...
string
)
(
int64
,
error
)
// query all data and map to [][]interface
// it converts data to [][column_index]value
// for example:
// var list []ParamsList
// qs.ValuesList(&list) // list[0][1] == "slene"
ValuesList
(
results
*
[]
ParamsList
,
exprs
...
string
)
(
int64
,
error
)
// query all data and map to []interface.
// it's designed for one column record set, auto change to []value, not [][column]value.
// for example:
// var list ParamsList
// qs.ValuesFlat(&list, "UserName") // list[0] == "slene"
ValuesFlat
(
result
*
ParamsList
,
expr
string
)
(
int64
,
error
)
// query all rows into map[string]interface with specify key and value column name.
// keyCol = "name", valueCol = "value"
// table data
// name | value
// total | 100
// found | 200
// to map[string]interface{}{
// "total": 100,
// "found": 200,
// }
RowsToMap
(
result
*
Params
,
keyCol
,
valueCol
string
)
(
int64
,
error
)
// query all rows into struct with specify key and value column name.
// keyCol = "name", valueCol = "value"
// table data
// name | value
// total | 100
// found | 200
// to struct {
// Total int
// Found int
// }
RowsToStruct
(
ptrStruct
interface
{},
keyCol
,
valueCol
string
)
(
int64
,
error
)
}
// QueryM2Mer model to model query struct
// all operations are on the m2m table only, will not affect the origin model table
type
QueryM2Mer
interface
{
// add models to origin models when creating queryM2M.
// example:
// m2m := orm.QueryM2M(post,"Tag")
// m2m.Add(&Tag1{},&Tag2{})
// for _,tag := range post.Tags{}{ ... }
// param could also be any of the follow
// []*Tag{{Id:3,Name: "TestTag1"}, {Id:4,Name: "TestTag2"}}
// &Tag{Id:5,Name: "TestTag3"}
// []interface{}{&Tag{Id:6,Name: "TestTag4"}}
// insert one or more rows to m2m table
// make sure the relation is defined in post model struct tag.
Add
(
...
interface
{})
(
int64
,
error
)
// remove models following the origin model relationship
// only delete rows from m2m table
// for example:
//tag3 := &Tag{Id:5,Name: "TestTag3"}
//num, err = m2m.Remove(tag3)
Remove
(
...
interface
{})
(
int64
,
error
)
// check model is existed in relationship of origin model
Exist
(
interface
{})
bool
// clean all models in related of origin model
Clear
()
(
int64
,
error
)
// count all related models of origin model
Count
()
(
int64
,
error
)
}
// RawPreparer raw query statement
type
RawPreparer
interface
{
Exec
(
...
interface
{})
(
sql
.
Result
,
error
)
...
...
@@ -100,16 +283,63 @@ type RawPreparer interface {
}
// RawSeter raw query seter
// create From Ormer.Raw
// for example:
// sql := fmt.Sprintf("SELECT %sid%s,%sname%s FROM %suser%s WHERE id = ?",Q,Q,Q,Q,Q,Q)
// rs := Ormer.Raw(sql, 1)
type
RawSeter
interface
{
//execute sql and get result
Exec
()
(
sql
.
Result
,
error
)
QueryRow
(
...
interface
{})
error
QueryRows
(
...
interface
{})
(
int64
,
error
)
//query data and map to container
//for example:
// var name string
// var id int
// rs.QueryRow(&id,&name) // id==2 name=="slene"
QueryRow
(
containers
...
interface
{})
error
// query data rows and map to container
// var ids []int
// var names []int
// query = fmt.Sprintf("SELECT 'id','name' FROM %suser%s", Q, Q)
// num, err = dORM.Raw(query).QueryRows(&ids,&names) // ids=>{1,2},names=>{"nobody","slene"}
QueryRows
(
containers
...
interface
{})
(
int64
,
error
)
SetArgs
(
...
interface
{})
RawSeter
Values
(
*
[]
Params
,
...
string
)
(
int64
,
error
)
ValuesList
(
*
[]
ParamsList
,
...
string
)
(
int64
,
error
)
ValuesFlat
(
*
ParamsList
,
...
string
)
(
int64
,
error
)
RowsToMap
(
*
Params
,
string
,
string
)
(
int64
,
error
)
RowsToStruct
(
interface
{},
string
,
string
)
(
int64
,
error
)
// query data to []map[string]interface
// see QuerySeter's Values
Values
(
container
*
[]
Params
,
cols
...
string
)
(
int64
,
error
)
// query data to [][]interface
// see QuerySeter's ValuesList
ValuesList
(
container
*
[]
ParamsList
,
cols
...
string
)
(
int64
,
error
)
// query data to []interface
// see QuerySeter's ValuesFlat
ValuesFlat
(
container
*
ParamsList
,
cols
...
string
)
(
int64
,
error
)
// query all rows into map[string]interface with specify key and value column name.
// keyCol = "name", valueCol = "value"
// table data
// name | value
// total | 100
// found | 200
// to map[string]interface{}{
// "total": 100,
// "found": 200,
// }
RowsToMap
(
result
*
Params
,
keyCol
,
valueCol
string
)
(
int64
,
error
)
// query all rows into struct with specify key and value column name.
// keyCol = "name", valueCol = "value"
// table data
// name | value
// total | 100
// found | 200
// to struct {
// Total int
// Found int
// }
RowsToStruct
(
ptrStruct
interface
{},
keyCol
,
valueCol
string
)
(
int64
,
error
)
// return prepared raw statement for used in times.
// for example:
// pre, err := dORM.Raw("INSERT INTO tag (name) VALUES (?)").Prepare()
// r, err := pre.Exec("name1") // INSERT INTO tag (name) VALUES (`name1`)
Prepare
()
(
RawPreparer
,
error
)
}
...
...
plugins/cors/cors_test.go
View file @
f6c508f1
...
...
@@ -225,8 +225,8 @@ func Benchmark_WithoutCORS(b *testing.B) {
ctx
.
Output
.
SetStatus
(
500
)
})
b
.
ResetTimer
()
for
i
:=
0
;
i
<
100
;
i
++
{
r
,
_
:=
http
.
NewRequest
(
"PUT"
,
"/foo"
,
nil
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
handler
.
ServeHTTP
(
recorder
,
r
)
}
}
...
...
@@ -246,8 +246,8 @@ func Benchmark_WithCORS(b *testing.B) {
ctx
.
Output
.
SetStatus
(
500
)
})
b
.
ResetTimer
()
for
i
:=
0
;
i
<
100
;
i
++
{
r
,
_
:=
http
.
NewRequest
(
"PUT"
,
"/foo"
,
nil
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
handler
.
ServeHTTP
(
recorder
,
r
)
}
}
staticfile_test.go
View file @
f6c508f1
...
...
@@ -2,8 +2,8 @@ package beego
import
(
"bytes"
"compress/flate"
"compress/gzip"
"compress/zlib"
"io"
"io/ioutil"
"os"
...
...
@@ -43,7 +43,7 @@ func TestOpenStaticFileGzip_1(t *testing.T) {
func
TestOpenStaticFileDeflate_1
(
t
*
testing
.
T
)
{
file
,
_
:=
os
.
Open
(
licenseFile
)
var
zipBuf
bytes
.
Buffer
fileWriter
,
_
:=
flate
.
NewWriter
(
&
zipBuf
,
flate
.
BestCompression
)
fileWriter
,
_
:=
zlib
.
NewWriterLevel
(
&
zipBuf
,
zlib
.
BestCompression
)
io
.
Copy
(
fileWriter
,
file
)
fileWriter
.
Close
()
content
,
_
:=
ioutil
.
ReadAll
(
&
zipBuf
)
...
...
tree.go
View file @
f6c508f1
...
...
@@ -334,7 +334,7 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
}
}
}
if
runObject
==
nil
{
if
runObject
==
nil
&&
len
(
t
.
fixrouters
)
>
0
{
// Filter the .json .xml .html extension
for
_
,
str
:=
range
allowSuffixExt
{
if
strings
.
HasSuffix
(
seg
,
str
)
{
...
...
@@ -353,11 +353,23 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
runObject
=
t
.
wildcard
.
match
(
pattern
,
append
(
wildcardValues
,
seg
),
ctx
)
}
if
runObject
==
nil
{
segments
:=
splitPath
(
pattern
)
if
runObject
==
nil
&&
len
(
t
.
leaves
)
>
0
{
wildcardValues
=
append
(
wildcardValues
,
seg
)
start
,
i
:=
0
,
0
for
;
i
<
len
(
pattern
);
i
++
{
if
pattern
[
i
]
==
'/'
{
if
i
!=
0
&&
start
<
len
(
pattern
)
{
wildcardValues
=
append
(
wildcardValues
,
pattern
[
start
:
i
])
}
start
=
i
+
1
continue
}
}
if
start
>
0
{
wildcardValues
=
append
(
wildcardValues
,
pattern
[
start
:
i
])
}
for
_
,
l
:=
range
t
.
leaves
{
if
ok
:=
l
.
match
(
append
(
wildcardValues
,
segments
...
)
,
ctx
);
ok
{
if
ok
:=
l
.
match
(
wildcardValues
,
ctx
);
ok
{
return
l
.
runObject
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment