diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
deleted file mode 100644
index 3a4d2e9a..00000000
--- a/.github/workflows/stale.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Mark stale issues and pull requests
-
-on:
- schedule:
- - cron: "30 1 * * *"
-
-jobs:
- stale:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/stale@v1
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- stale-issue-message: 'This issue is inactive for a long time.'
- stale-pr-message: 'This PR is inactive for a long time'
- stale-issue-label: 'inactive-issue'
- stale-pr-label: 'inactive-pr'
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 304c4b73..e1b65291 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,9 +4,3 @@
*.swp
*.swo
beego.iml
-
-_beeTmp/
-_beeTmp2/
-pkg/_beeTmp/
-pkg/_beeTmp2/
-test/tmp/
diff --git a/.travis.yml b/.travis.yml
index 973b40ef..c019c999 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,59 +1,30 @@
language: go
go:
- - "1.14.x"
+ - "1.13.x"
services:
- redis-server
- mysql
- postgresql
- memcached
- - docker
env:
global:
- GO_REPO_FULLNAME="github.com/astaxie/beego"
matrix:
- ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db
- ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
- - ORM_DRIVER=mysql export ORM_SOURCE="root:@/orm_test?charset=utf8"
before_install:
- # link the local repo with ${GOPATH}/src//
- - GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*}
- # relies on GOPATH to contain only one directory...
- - mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE}
- - ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME}
- - cd ${GOPATH}/src/${GO_REPO_FULLNAME}
- # get and build ssdb
- - git clone git://github.com/ideawu/ssdb.git
- - cd ssdb
- - make
- - cd ..
- # - prepare etcd
- # - prepare for etcd unit tests
- - rm -rf /tmp/etcd-data.tmp
- - mkdir -p /tmp/etcd-data.tmp
- - docker rmi gcr.io/etcd-development/etcd:v3.3.25 || true &&
- docker run -d
- -p 2379:2379
- -p 2380:2380
- --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data
- --name etcd-gcr-v3.3.25
- gcr.io/etcd-development/etcd:v3.3.25
- /usr/local/bin/etcd
- --name s1
- --data-dir /etcd-data
- --listen-client-urls http://0.0.0.0:2379
- --advertise-client-urls http://0.0.0.0:2379
- --listen-peer-urls http://0.0.0.0:2380
- --initial-advertise-peer-urls http://0.0.0.0:2380
- --initial-cluster s1=http://0.0.0.0:2380
- --initial-cluster-token tkn
- --initial-cluster-state new
- - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23"
- - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true"
- - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11"
- - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello"
- - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test"
- - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key"
+ # link the local repo with ${GOPATH}/src//
+ - GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*}
+ # relies on GOPATH to contain only one directory...
+ - mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE}
+ - ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME}
+ - cd ${GOPATH}/src/${GO_REPO_FULLNAME}
+ # get and build ssdb
+ - git clone git://github.com/ideawu/ssdb.git
+ - cd ssdb
+ - make
+ - cd ..
install:
- go get github.com/lib/pq
- go get github.com/go-sql-driver/mysql
@@ -80,10 +51,7 @@ install:
- go get -u golang.org/x/lint/golint
- go get -u github.com/go-redis/redis
before_script:
-
- # -
- psql --version
- # - prepare for orm unit tests
- sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
- sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi"
- sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi"
@@ -95,11 +63,11 @@ after_script:
- killall -w ssdb-server
- rm -rf ./res/var/*
script:
- - go test ./...
- - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" ./
+ - go test -v ./...
+ - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024"
- unconvert $(go list ./... | grep -v /vendor/)
- ineffassign .
- find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s
- golint ./...
addons:
- postgresql: "9.6"
\ No newline at end of file
+ postgresql: "9.6"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cb279cbb..9d511616 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -7,58 +7,17 @@ It is the work of hundreds of contributors. We appreciate your help!
Here are instructions to get you started. They are probably not perfect,
please let us know if anything feels wrong or incomplete.
-## Prepare environment
-
-Firstly, install some tools. Execute those commands **outside** the project. Or those command will modify go.mod file.
-
-```shell script
-go get -u golang.org/x/tools/cmd/goimports
-
-go get -u github.com/gordonklaus/ineffassign
-```
-
-Put those lines into your pre-commit githook script:
-```shell script
-goimports -w -format-only ./
-
-ineffassign .
-
-staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" ./
-```
-
-## Prepare middleware
-
-Beego uses many middlewares, including MySQL, Redis, SSDB and so on.
-
-We provide docker compose file to start all middlewares.
-
-You can run:
-```shell script
-docker-compose -f scripts/test_docker_compose.yml up -d
-```
-Unit tests read addresses from environment, here is an example:
-```shell script
-export ORM_DRIVER=mysql
-export ORM_SOURCE="beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8"
-export MEMCACHE_ADDR="192.168.0.105:11211"
-export REDIS_ADDR="192.168.0.105:6379"
-export SSDB_ADDR="192.168.0.105:8888"
-```
-
-
## Contribution guidelines
### Pull requests
First of all. beego follow the gitflow. So please send you pull request
-to **develop-2** branch. We will close the pull request to master branch.
+to **develop** branch. We will close the pull request to master branch.
We are always happy to receive pull requests, and do our best to
review them as fast as possible. Not sure if that typo is worth a pull
request? Do it! We will appreciate it.
-Don't forget to rebase your commits!
-
If your pull request is not accepted on the first try, don't be
discouraged! Sometimes we can make a mistake, please do more explaining
for us. We will appreciate it.
@@ -89,5 +48,5 @@ documenting your bug report or improvement proposal. If it does, it
never hurts to add a quick "+1" or "I have this problem too". This will
help prioritize the most common problems and requests.
-Also, if you don't know how to use it. please make sure you have read through
+Also if you don't know how to use it. please make sure you have read though
the docs in http://beego.me/docs
\ No newline at end of file
diff --git a/README.md b/README.md
index 934fc429..3b414c6f 100644
--- a/README.md
+++ b/README.md
@@ -8,21 +8,6 @@ It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific feature
## Quick Start
-###### Please see [Documentation](http://beego.me/docs) for more.
-
-###### [beego-example](https://github.com/beego-dev/beego-example)
-
-### Web Application
-
-#### Create `hello` directory, cd `hello` directory
-
- mkdir hello
- cd hello
-
-#### Init module
-
- go mod init
-
#### Download and install
go get github.com/astaxie/beego
@@ -31,10 +16,10 @@ It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific feature
```go
package main
-import "github.com/astaxie/beego/server/web"
+import "github.com/astaxie/beego"
func main(){
- web.Run()
+ beego.Run()
}
```
#### Build and run
@@ -46,204 +31,9 @@ func main(){
Congratulations! You've just built your first **beego** app.
-### Using ORM module
-
-```go
-
-package main
-
-import (
- "github.com/astaxie/beego/client/orm"
- "github.com/astaxie/beego/core/logs"
- _ "github.com/go-sql-driver/mysql"
-)
-
-// User -
-type User struct {
- ID int `orm:"column(id)"`
- Name string `orm:"column(name)"`
-}
-
-func init() {
- // need to register models in init
- orm.RegisterModel(new(User))
-
- // need to register db driver
- orm.RegisterDriver("mysql", orm.DRMySQL)
-
- // need to register default database
- orm.RegisterDataBase("default", "mysql", "beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8")
-}
-
-func main() {
- // automatically build table
- orm.RunSyncdb("default", false, true)
-
- // create orm object, and it will use `default` database
- o := orm.NewOrm()
-
- // data
- user := new(User)
- user.Name = "mike"
-
- // insert data
- id, err := o.Insert(user)
- if err != nil {
- logs.Info(err)
- }
-
- // ...
-}
-```
-
-### Using httplib as http client
-```go
-package main
-
-import (
- "github.com/astaxie/beego/client/httplib"
- "github.com/astaxie/beego/core/logs"
-)
-
-func main() {
- // Get, more methods please read docs
- req := httplib.Get("http://beego.me/")
- str, err := req.String()
- if err != nil {
- logs.Error(err)
- }
- logs.Info(str)
-}
-
-```
-
-### Using config module
-
-```go
-package main
-
-import (
- "context"
-
- "github.com/astaxie/beego/core/config"
- "github.com/astaxie/beego/core/logs"
-)
-
-var (
- ConfigFile = "./app.conf"
-)
-
-func main() {
- cfg, err := config.NewConfig("ini", ConfigFile)
- if err != nil {
- logs.Critical("An error occurred:", err)
- panic(err)
- }
- res, _ := cfg.String(context.Background(), "name")
- logs.Info("load config name is", res)
-}
-```
-### Using logs module
-```go
-package main
-
-import (
- "github.com/astaxie/beego/core/logs"
-)
-
-func main() {
- err := logs.SetLogger(logs.AdapterFile, `{"filename":"project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`)
- if err != nil {
- panic(err)
- }
- logs.Info("hello beego")
-}
-```
-### Using timed task
-
-```go
-package main
-
-import (
- "context"
- "time"
-
- "github.com/astaxie/beego/core/logs"
- "github.com/astaxie/beego/task"
-)
-
-func main() {
- // create a task
- tk1 := task.NewTask("tk1", "0/3 * * * * *", func(ctx context.Context) error { logs.Info("tk1"); return nil })
-
- // check task
- err := tk1.Run(context.Background())
- if err != nil {
- logs.Error(err)
- }
-
- // add task to global todolist
- task.AddTask("tk1", tk1)
-
- // start tasks
- task.StartTask()
-
- // wait 12 second
- time.Sleep(12 * time.Second)
- defer task.StopTask()
-}
-```
-
-### Using cache module
-
-```go
-package main
-
-import (
- "context"
- "time"
-
- "github.com/astaxie/beego/client/cache"
-
- // don't forget this
- _ "github.com/astaxie/beego/client/cache/redis"
-
- "github.com/astaxie/beego/core/logs"
-)
-
-func main() {
- // create cache
- bm, err := cache.NewCache("redis", `{"key":"default", "conn":":6379", "password":"123456", "dbNum":"0"}`)
- if err != nil {
- logs.Error(err)
- }
-
- // put
- isPut := bm.Put(context.Background(), "astaxie", 1, time.Second*10)
- logs.Info(isPut)
-
- isPut = bm.Put(context.Background(), "hello", "world", time.Second*10)
- logs.Info(isPut)
-
- // get
- result, _ := bm.Get(context.Background(),"astaxie")
- logs.Info(string(result.([]byte)))
-
- multiResult, _ := bm.GetMulti(context.Background(), []string{"astaxie", "hello"})
- for i := range multiResult {
- logs.Info(string(multiResult[i].([]byte)))
- }
-
- // isExist
- isExist, _ := bm.IsExist(context.Background(), "astaxie")
- logs.Info(isExist)
-
- // delete
- isDelete := bm.Delete(context.Background(), "astaxie")
- logs.Info(isDelete)
-}
-```
+###### Please see [Documentation](http://beego.me/docs) for more.
+###### [beego-example](https://github.com/beego-dev/beego-example)
## Features
diff --git a/adapter/admin.go b/adapter/admin.go
deleted file mode 100644
index e555f59e..00000000
--- a/adapter/admin.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
- "time"
-
- _ "github.com/astaxie/beego/core/governor"
- "github.com/astaxie/beego/server/web"
-)
-
-// FilterMonitorFunc is default monitor filter when admin module is enable.
-// if this func returns, admin module records qps for this request by condition of this function logic.
-// usage:
-// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
-// if method == "POST" {
-// return false
-// }
-// if t.Nanoseconds() < 100 {
-// return false
-// }
-// if strings.HasPrefix(requestPath, "/astaxie") {
-// return false
-// }
-// return true
-// }
-// beego.FilterMonitorFunc = MyFilterMonitor.
-var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
-
-// PrintTree prints all registered routers.
-func PrintTree() M {
- return (M)(web.BeeApp.PrintTree())
-}
diff --git a/adapter/app.go b/adapter/app.go
deleted file mode 100644
index e20cd9d2..00000000
--- a/adapter/app.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
- "net/http"
-
- context2 "github.com/astaxie/beego/adapter/context"
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
-)
-
-var (
- // BeeApp is an application instance
- BeeApp *App
-)
-
-func init() {
- // create beego application
- BeeApp = (*App)(web.BeeApp)
-}
-
-// App defines beego application with a new PatternServeMux.
-type App web.HttpServer
-
-// NewApp returns a new beego application.
-func NewApp() *App {
- return (*App)(web.NewHttpSever())
-}
-
-// MiddleWare function for http.Handler
-type MiddleWare web.MiddleWare
-
-// Run beego application.
-func (app *App) Run(mws ...MiddleWare) {
- newMws := oldMiddlewareToNew(mws)
- (*web.HttpServer)(app).Run("", newMws...)
-}
-
-func oldMiddlewareToNew(mws []MiddleWare) []web.MiddleWare {
- newMws := make([]web.MiddleWare, 0, len(mws))
- for _, old := range mws {
- newMws = append(newMws, (web.MiddleWare)(old))
- }
- return newMws
-}
-
-// Router adds a patterned controller handler to BeeApp.
-// it's an alias method of HttpServer.Router.
-// usage:
-// simple router
-// beego.Router("/admin", &admin.UserController{})
-// beego.Router("/admin/index", &admin.ArticleController{})
-//
-// regex router
-//
-// beego.Router("/api/:id([0-9]+)", &controllers.RController{})
-//
-// custom rules
-// beego.Router("/api/list",&RestController{},"*:ListFood")
-// beego.Router("/api/create",&RestController{},"post:CreateFood")
-// beego.Router("/api/update",&RestController{},"put:UpdateFood")
-// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
-func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
- return (*App)(web.Router(rootpath, c, mappingMethods...))
-}
-
-// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
-// in web applications that inherit most routes from a base webapp via the underscore
-// import, and aim to overwrite only certain paths.
-// The method parameter can be empty or "*" for all HTTP methods, or a particular
-// method type (e.g. "GET" or "POST") for selective removal.
-//
-// Usage (replace "GET" with "*" for all methods):
-// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
-// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
-func UnregisterFixedRoute(fixedRoute string, method string) *App {
- return (*App)(web.UnregisterFixedRoute(fixedRoute, method))
-}
-
-// Include will generate router file in the router/xxx.go from the controller's comments
-// usage:
-// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
-// type BankAccount struct{
-// beego.Controller
-// }
-//
-// register the function
-// func (b *BankAccount)Mapping(){
-// b.Mapping("ShowAccount" , b.ShowAccount)
-// b.Mapping("ModifyAccount", b.ModifyAccount)
-// }
-//
-// //@router /account/:id [get]
-// func (b *BankAccount) ShowAccount(){
-// //logic
-// }
-//
-//
-// //@router /account/:id [post]
-// func (b *BankAccount) ModifyAccount(){
-// //logic
-// }
-//
-// the comments @router url methodlist
-// url support all the function Router's pattern
-// methodlist [get post head put delete options *]
-func Include(cList ...ControllerInterface) *App {
- newList := oldToNewCtrlIntfs(cList)
- return (*App)(web.Include(newList...))
-}
-
-func oldToNewCtrlIntfs(cList []ControllerInterface) []web.ControllerInterface {
- newList := make([]web.ControllerInterface, 0, len(cList))
- for _, c := range cList {
- newList = append(newList, c)
- }
- return newList
-}
-
-// RESTRouter adds a restful controller handler to BeeApp.
-// its' controller implements beego.ControllerInterface and
-// defines a param "pattern/:objectId" to visit each resource.
-func RESTRouter(rootpath string, c ControllerInterface) *App {
- return (*App)(web.RESTRouter(rootpath, c))
-}
-
-// AutoRouter adds defined controller handler to BeeApp.
-// it's same to HttpServer.AutoRouter.
-// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
-// visit the url /main/list to exec List function or /main/page to exec Page function.
-func AutoRouter(c ControllerInterface) *App {
- return (*App)(web.AutoRouter(c))
-}
-
-// AutoPrefix adds controller handler to BeeApp with prefix.
-// it's same to HttpServer.AutoRouterWithPrefix.
-// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page,
-// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
-func AutoPrefix(prefix string, c ControllerInterface) *App {
- return (*App)(web.AutoPrefix(prefix, c))
-}
-
-// Get used to register router for Get method
-// usage:
-// beego.Get("/", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Get(rootpath string, f FilterFunc) *App {
- return (*App)(web.Get(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Post used to register router for Post method
-// usage:
-// beego.Post("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Post(rootpath string, f FilterFunc) *App {
- return (*App)(web.Post(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Delete used to register router for Delete method
-// usage:
-// beego.Delete("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Delete(rootpath string, f FilterFunc) *App {
- return (*App)(web.Delete(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Put used to register router for Put method
-// usage:
-// beego.Put("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Put(rootpath string, f FilterFunc) *App {
- return (*App)(web.Put(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Head used to register router for Head method
-// usage:
-// beego.Head("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Head(rootpath string, f FilterFunc) *App {
- return (*App)(web.Head(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Options used to register router for Options method
-// usage:
-// beego.Options("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Options(rootpath string, f FilterFunc) *App {
- return (*App)(web.Options(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Patch used to register router for Patch method
-// usage:
-// beego.Patch("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Patch(rootpath string, f FilterFunc) *App {
- return (*App)(web.Patch(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Any used to register router for all methods
-// usage:
-// beego.Any("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Any(rootpath string, f FilterFunc) *App {
- return (*App)(web.Any(rootpath, func(ctx *context.Context) {
- f((*context2.Context)(ctx))
- }))
-}
-
-// Handler used to register a Handler router
-// usage:
-// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
-// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
-// }))
-func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
- return (*App)(web.Handler(rootpath, h, options))
-}
-
-// InsertFilter adds a FilterFunc with pattern condition and action constant.
-// The pos means action constant including
-// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
-// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
-func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
- opts := oldToNewFilterOpts(params)
- return (*App)(web.InsertFilter(pattern, pos, func(ctx *context.Context) {
- filter((*context2.Context)(ctx))
- }, opts...))
-}
diff --git a/adapter/beego.go b/adapter/beego.go
deleted file mode 100644
index bbe37db8..00000000
--- a/adapter/beego.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/server/web"
-)
-
-const (
-
- // VERSION represent beego web framework version.
- VERSION = beego.VERSION
-
- // DEV is for develop
- DEV = web.DEV
- // PROD is for production
- PROD = web.PROD
-)
-
-// M is Map shortcut
-type M web.M
-
-// Hook function to run
-type hookfunc func() error
-
-var (
- hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc
-)
-
-// AddAPPStartHook is used to register the hookfunc
-// The hookfuncs will run in beego.Run()
-// such as initiating session , starting middleware , building template, starting admin control and so on.
-func AddAPPStartHook(hf ...hookfunc) {
- for _, f := range hf {
- web.AddAPPStartHook(func() error {
- return f()
- })
- }
-}
-
-// Run beego application.
-// beego.Run() default run on HttpPort
-// beego.Run("localhost")
-// beego.Run(":8089")
-// beego.Run("127.0.0.1:8089")
-func Run(params ...string) {
- web.Run(params...)
-}
-
-// RunWithMiddleWares Run beego application with middlewares.
-func RunWithMiddleWares(addr string, mws ...MiddleWare) {
- newMws := oldMiddlewareToNew(mws)
- web.RunWithMiddleWares(addr, newMws...)
-}
-
-// TestBeegoInit is for test package init
-func TestBeegoInit(ap string) {
- web.TestBeegoInit(ap)
-}
-
-// InitBeegoBeforeTest is for test package init
-func InitBeegoBeforeTest(appConfigPath string) {
- web.InitBeegoBeforeTest(appConfigPath)
-}
diff --git a/adapter/build_info.go b/adapter/build_info.go
deleted file mode 100644
index 1e8dacf0..00000000
--- a/adapter/build_info.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2020 astaxie
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-var (
- BuildVersion string
- BuildGitRevision string
- BuildStatus string
- BuildTag string
- BuildTime string
-
- GoVersion string
-
- GitBranch string
-)
diff --git a/adapter/cache/cache_adapter.go b/adapter/cache/cache_adapter.go
deleted file mode 100644
index 3bfd0bf8..00000000
--- a/adapter/cache/cache_adapter.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cache
-
-import (
- "context"
- "time"
-
- "github.com/astaxie/beego/client/cache"
-)
-
-type newToOldCacheAdapter struct {
- delegate cache.Cache
-}
-
-func (c *newToOldCacheAdapter) Get(key string) interface{} {
- res, _ := c.delegate.Get(context.Background(), key)
- return res
-}
-
-func (c *newToOldCacheAdapter) GetMulti(keys []string) []interface{} {
- res, _ := c.delegate.GetMulti(context.Background(), keys)
- return res
-}
-
-func (c *newToOldCacheAdapter) Put(key string, val interface{}, timeout time.Duration) error {
- return c.delegate.Put(context.Background(), key, val, timeout)
-}
-
-func (c *newToOldCacheAdapter) Delete(key string) error {
- return c.delegate.Delete(context.Background(), key)
-}
-
-func (c *newToOldCacheAdapter) Incr(key string) error {
- return c.delegate.Incr(context.Background(), key)
-}
-
-func (c *newToOldCacheAdapter) Decr(key string) error {
- return c.delegate.Decr(context.Background(), key)
-}
-
-func (c *newToOldCacheAdapter) IsExist(key string) bool {
- res, err := c.delegate.IsExist(context.Background(), key)
- return res && err == nil
-}
-
-func (c *newToOldCacheAdapter) ClearAll() error {
- return c.delegate.ClearAll(context.Background())
-}
-
-func (c *newToOldCacheAdapter) StartAndGC(config string) error {
- return c.delegate.StartAndGC(config)
-}
-
-func CreateNewToOldCacheAdapter(delegate cache.Cache) Cache {
- return &newToOldCacheAdapter{
- delegate: delegate,
- }
-}
-
-type oldToNewCacheAdapter struct {
- old Cache
-}
-
-func (o *oldToNewCacheAdapter) Get(ctx context.Context, key string) (interface{}, error) {
- return o.old.Get(key), nil
-}
-
-func (o *oldToNewCacheAdapter) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
- return o.old.GetMulti(keys), nil
-}
-
-func (o *oldToNewCacheAdapter) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
- return o.old.Put(key, val, timeout)
-}
-
-func (o *oldToNewCacheAdapter) Delete(ctx context.Context, key string) error {
- return o.old.Delete(key)
-}
-
-func (o *oldToNewCacheAdapter) Incr(ctx context.Context, key string) error {
- return o.old.Incr(key)
-}
-
-func (o *oldToNewCacheAdapter) Decr(ctx context.Context, key string) error {
- return o.old.Decr(key)
-}
-
-func (o *oldToNewCacheAdapter) IsExist(ctx context.Context, key string) (bool, error) {
- return o.old.IsExist(key), nil
-}
-
-func (o *oldToNewCacheAdapter) ClearAll(ctx context.Context) error {
- return o.old.ClearAll()
-}
-
-func (o *oldToNewCacheAdapter) StartAndGC(config string) error {
- return o.old.StartAndGC(config)
-}
-
-func CreateOldToNewAdapter(old Cache) cache.Cache {
- return &oldToNewCacheAdapter{
- old: old,
- }
-}
diff --git a/adapter/cache/conv.go b/adapter/cache/conv.go
deleted file mode 100644
index 18b8a255..00000000
--- a/adapter/cache/conv.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cache
-
-import (
- "github.com/astaxie/beego/client/cache"
-)
-
-// GetString convert interface to string.
-func GetString(v interface{}) string {
- return cache.GetString(v)
-}
-
-// GetInt convert interface to int.
-func GetInt(v interface{}) int {
- return cache.GetInt(v)
-}
-
-// GetInt64 convert interface to int64.
-func GetInt64(v interface{}) int64 {
- return cache.GetInt64(v)
-}
-
-// GetFloat64 convert interface to float64.
-func GetFloat64(v interface{}) float64 {
- return cache.GetFloat64(v)
-}
-
-// GetBool convert interface to bool.
-func GetBool(v interface{}) bool {
- return cache.GetBool(v)
-}
diff --git a/adapter/cache/file.go b/adapter/cache/file.go
deleted file mode 100644
index 74eb980a..00000000
--- a/adapter/cache/file.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cache
-
-import (
- "github.com/astaxie/beego/client/cache"
-)
-
-// NewFileCache Create new file cache with no config.
-// the level and expiry need set in method StartAndGC as config string.
-func NewFileCache() Cache {
- // return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
- return CreateNewToOldCacheAdapter(cache.NewFileCache())
-}
-
-func init() {
- Register("file", NewFileCache)
-}
diff --git a/adapter/cache/memcache/memcache.go b/adapter/cache/memcache/memcache.go
deleted file mode 100644
index b4da1bfe..00000000
--- a/adapter/cache/memcache/memcache.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package memcache for cache provider
-//
-// depend on github.com/bradfitz/gomemcache/memcache
-//
-// go install github.com/bradfitz/gomemcache/memcache
-//
-// Usage:
-// import(
-// _ "github.com/astaxie/beego/cache/memcache"
-// "github.com/astaxie/beego/cache"
-// )
-//
-// bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
-//
-// more docs http://beego.me/docs/module/cache.md
-package memcache
-
-import (
- "github.com/astaxie/beego/adapter/cache"
- "github.com/astaxie/beego/client/cache/memcache"
-)
-
-// NewMemCache create new memcache adapter.
-func NewMemCache() cache.Cache {
- return cache.CreateNewToOldCacheAdapter(memcache.NewMemCache())
-}
-
-func init() {
- cache.Register("memcache", NewMemCache)
-}
diff --git a/adapter/cache/memory.go b/adapter/cache/memory.go
deleted file mode 100644
index cf6e3992..00000000
--- a/adapter/cache/memory.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cache
-
-import (
- "github.com/astaxie/beego/client/cache"
-)
-
-// NewMemoryCache returns a new MemoryCache.
-func NewMemoryCache() Cache {
- return CreateNewToOldCacheAdapter(cache.NewMemoryCache())
-}
-
-func init() {
- Register("memory", NewMemoryCache)
-}
diff --git a/adapter/cache/redis/redis.go b/adapter/cache/redis/redis.go
deleted file mode 100644
index 3562057d..00000000
--- a/adapter/cache/redis/redis.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package redis for cache provider
-//
-// depend on github.com/gomodule/redigo/redis
-//
-// go install github.com/gomodule/redigo/redis
-//
-// Usage:
-// import(
-// _ "github.com/astaxie/beego/cache/redis"
-// "github.com/astaxie/beego/cache"
-// )
-//
-// bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`)
-//
-// more docs http://beego.me/docs/module/cache.md
-package redis
-
-import (
- "github.com/astaxie/beego/adapter/cache"
- redis2 "github.com/astaxie/beego/client/cache/redis"
-)
-
-var (
- // DefaultKey the collection name of redis for cache adapter.
- DefaultKey = "beecacheRedis"
-)
-
-// NewRedisCache create new redis cache with default collection name.
-func NewRedisCache() cache.Cache {
- return cache.CreateNewToOldCacheAdapter(redis2.NewRedisCache())
-}
-
-func init() {
- cache.Register("redis", NewRedisCache)
-}
diff --git a/adapter/cache/ssdb/ssdb.go b/adapter/cache/ssdb/ssdb.go
deleted file mode 100644
index df552043..00000000
--- a/adapter/cache/ssdb/ssdb.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package ssdb
-
-import (
- "github.com/astaxie/beego/adapter/cache"
- ssdb2 "github.com/astaxie/beego/client/cache/ssdb"
-)
-
-// NewSsdbCache create new ssdb adapter.
-func NewSsdbCache() cache.Cache {
- return cache.CreateNewToOldCacheAdapter(ssdb2.NewSsdbCache())
-}
-
-func init() {
- cache.Register("ssdb", NewSsdbCache)
-}
diff --git a/adapter/config.go b/adapter/config.go
deleted file mode 100644
index 6280b8f8..00000000
--- a/adapter/config.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
- "github.com/astaxie/beego/adapter/session"
- newCfg "github.com/astaxie/beego/core/config"
- "github.com/astaxie/beego/server/web"
-)
-
-// Config is the main struct for BConfig
-type Config web.Config
-
-// Listen holds for http and https related config
-type Listen web.Listen
-
-// WebConfig holds web related config
-type WebConfig web.WebConfig
-
-// SessionConfig holds session related config
-type SessionConfig web.SessionConfig
-
-// LogConfig holds Log related config
-type LogConfig web.LogConfig
-
-var (
- // BConfig is the default config for Application
- BConfig *Config
- // AppConfig is the instance of Config, store the config information from file
- AppConfig *beegoAppConfig
- // AppPath is the absolute path to the app
- AppPath string
- // GlobalSessions is the instance for the session manager
- GlobalSessions *session.Manager
-
- // appConfigPath is the path to the config files
- appConfigPath string
- // appConfigProvider is the provider for the config, default is ini
- appConfigProvider = "ini"
- // WorkPath is the absolute path to project root directory
- WorkPath string
-)
-
-func init() {
- BConfig = (*Config)(web.BConfig)
- AppPath = web.AppPath
-
- WorkPath = web.WorkPath
-
- AppConfig = &beegoAppConfig{innerConfig: (newCfg.Configer)(web.AppConfig)}
-}
-
-// LoadAppConfig allow developer to apply a config file
-func LoadAppConfig(adapterName, configPath string) error {
- return web.LoadAppConfig(adapterName, configPath)
-}
-
-type beegoAppConfig struct {
- innerConfig newCfg.Configer
-}
-
-func (b *beegoAppConfig) Set(key, val string) error {
- if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
- return b.innerConfig.Set(key, val)
- }
- return nil
-}
-
-func (b *beegoAppConfig) String(key string) string {
- if v, err := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" && err != nil {
- return v
- }
- res, _ := b.innerConfig.String(key)
- return res
-}
-
-func (b *beegoAppConfig) Strings(key string) []string {
- if v, err := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 && err != nil {
- return v
- }
- res, _ := b.innerConfig.Strings(key)
- return res
-}
-
-func (b *beegoAppConfig) Int(key string) (int, error) {
- if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Int(key)
-}
-
-func (b *beegoAppConfig) Int64(key string) (int64, error) {
- if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Int64(key)
-}
-
-func (b *beegoAppConfig) Bool(key string) (bool, error) {
- if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Bool(key)
-}
-
-func (b *beegoAppConfig) Float(key string) (float64, error) {
- if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Float(key)
-}
-
-func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
- if v := b.String(key); v != "" {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
- if v := b.Strings(key); len(v) != 0 {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
- if v, err := b.Int(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
- if v, err := b.Int64(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
- if v, err := b.Bool(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
- if v, err := b.Float(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
- return b.innerConfig.DIY(key)
-}
-
-func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
- return b.innerConfig.GetSection(section)
-}
-
-func (b *beegoAppConfig) SaveConfigFile(filename string) error {
- return b.innerConfig.SaveConfigFile(filename)
-}
diff --git a/adapter/config/adapter.go b/adapter/config/adapter.go
deleted file mode 100644
index 0a9e1d0c..00000000
--- a/adapter/config/adapter.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package config
-
-import (
- "github.com/pkg/errors"
-
- "github.com/astaxie/beego/core/config"
-)
-
-type newToOldConfigerAdapter struct {
- delegate config.Configer
-}
-
-func (c *newToOldConfigerAdapter) Set(key, val string) error {
- return c.delegate.Set(key, val)
-}
-
-func (c *newToOldConfigerAdapter) String(key string) string {
- res, _ := c.delegate.String(key)
- return res
-}
-
-func (c *newToOldConfigerAdapter) Strings(key string) []string {
- res, _ := c.delegate.Strings(key)
- return res
-}
-
-func (c *newToOldConfigerAdapter) Int(key string) (int, error) {
- return c.delegate.Int(key)
-}
-
-func (c *newToOldConfigerAdapter) Int64(key string) (int64, error) {
- return c.delegate.Int64(key)
-}
-
-func (c *newToOldConfigerAdapter) Bool(key string) (bool, error) {
- return c.delegate.Bool(key)
-}
-
-func (c *newToOldConfigerAdapter) Float(key string) (float64, error) {
- return c.delegate.Float(key)
-}
-
-func (c *newToOldConfigerAdapter) DefaultString(key string, defaultVal string) string {
- return c.delegate.DefaultString(key, defaultVal)
-}
-
-func (c *newToOldConfigerAdapter) DefaultStrings(key string, defaultVal []string) []string {
- return c.delegate.DefaultStrings(key, defaultVal)
-}
-
-func (c *newToOldConfigerAdapter) DefaultInt(key string, defaultVal int) int {
- return c.delegate.DefaultInt(key, defaultVal)
-}
-
-func (c *newToOldConfigerAdapter) DefaultInt64(key string, defaultVal int64) int64 {
- return c.delegate.DefaultInt64(key, defaultVal)
-}
-
-func (c *newToOldConfigerAdapter) DefaultBool(key string, defaultVal bool) bool {
- return c.delegate.DefaultBool(key, defaultVal)
-}
-
-func (c *newToOldConfigerAdapter) DefaultFloat(key string, defaultVal float64) float64 {
- return c.delegate.DefaultFloat(key, defaultVal)
-}
-
-func (c *newToOldConfigerAdapter) DIY(key string) (interface{}, error) {
- return c.delegate.DIY(key)
-}
-
-func (c *newToOldConfigerAdapter) GetSection(section string) (map[string]string, error) {
- return c.delegate.GetSection(section)
-}
-
-func (c *newToOldConfigerAdapter) SaveConfigFile(filename string) error {
- return c.delegate.SaveConfigFile(filename)
-}
-
-type oldToNewConfigerAdapter struct {
- delegate Configer
-}
-
-func (o *oldToNewConfigerAdapter) Set(key, val string) error {
- return o.delegate.Set(key, val)
-}
-
-func (o *oldToNewConfigerAdapter) String(key string) (string, error) {
- return o.delegate.String(key), nil
-}
-
-func (o *oldToNewConfigerAdapter) Strings(key string) ([]string, error) {
- return o.delegate.Strings(key), nil
-}
-
-func (o *oldToNewConfigerAdapter) Int(key string) (int, error) {
- return o.delegate.Int(key)
-}
-
-func (o *oldToNewConfigerAdapter) Int64(key string) (int64, error) {
- return o.delegate.Int64(key)
-}
-
-func (o *oldToNewConfigerAdapter) Bool(key string) (bool, error) {
- return o.delegate.Bool(key)
-}
-
-func (o *oldToNewConfigerAdapter) Float(key string) (float64, error) {
- return o.delegate.Float(key)
-}
-
-func (o *oldToNewConfigerAdapter) DefaultString(key string, defaultVal string) string {
- return o.delegate.DefaultString(key, defaultVal)
-}
-
-func (o *oldToNewConfigerAdapter) DefaultStrings(key string, defaultVal []string) []string {
- return o.delegate.DefaultStrings(key, defaultVal)
-}
-
-func (o *oldToNewConfigerAdapter) DefaultInt(key string, defaultVal int) int {
- return o.delegate.DefaultInt(key, defaultVal)
-}
-
-func (o *oldToNewConfigerAdapter) DefaultInt64(key string, defaultVal int64) int64 {
- return o.delegate.DefaultInt64(key, defaultVal)
-}
-
-func (o *oldToNewConfigerAdapter) DefaultBool(key string, defaultVal bool) bool {
- return o.delegate.DefaultBool(key, defaultVal)
-}
-
-func (o *oldToNewConfigerAdapter) DefaultFloat(key string, defaultVal float64) float64 {
- return o.delegate.DefaultFloat(key, defaultVal)
-}
-
-func (o *oldToNewConfigerAdapter) DIY(key string) (interface{}, error) {
- return o.delegate.DIY(key)
-}
-
-func (o *oldToNewConfigerAdapter) GetSection(section string) (map[string]string, error) {
- return o.delegate.GetSection(section)
-}
-
-func (o *oldToNewConfigerAdapter) Unmarshaler(prefix string, obj interface{}, opt ...config.DecodeOption) error {
- return errors.New("unsupported operation, please use actual config.Configer")
-}
-
-func (o *oldToNewConfigerAdapter) Sub(key string) (config.Configer, error) {
- return nil, errors.New("unsupported operation, please use actual config.Configer")
-}
-
-func (o *oldToNewConfigerAdapter) OnChange(key string, fn func(value string)) {
- // do nothing
-}
-
-func (o *oldToNewConfigerAdapter) SaveConfigFile(filename string) error {
- return o.delegate.SaveConfigFile(filename)
-}
-
-type oldToNewConfigAdapter struct {
- delegate Config
-}
-
-func (o *oldToNewConfigAdapter) Parse(key string) (config.Configer, error) {
- old, err := o.delegate.Parse(key)
- if err != nil {
- return nil, err
- }
- return &oldToNewConfigerAdapter{delegate: old}, nil
-}
-
-func (o *oldToNewConfigAdapter) ParseData(data []byte) (config.Configer, error) {
- old, err := o.delegate.ParseData(data)
- if err != nil {
- return nil, err
- }
- return &oldToNewConfigerAdapter{delegate: old}, nil
-}
diff --git a/adapter/config/config.go b/adapter/config/config.go
deleted file mode 100644
index 703555cd..00000000
--- a/adapter/config/config.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package config is used to parse config.
-// Usage:
-// import "github.com/astaxie/beego/config"
-// Examples.
-//
-// cnf, err := config.NewConfig("ini", "config.conf")
-//
-// cnf APIS:
-//
-// cnf.Set(key, val string) error
-// cnf.String(key string) string
-// cnf.Strings(key string) []string
-// cnf.Int(key string) (int, error)
-// cnf.Int64(key string) (int64, error)
-// cnf.Bool(key string) (bool, error)
-// cnf.Float(key string) (float64, error)
-// cnf.DefaultString(key string, defaultVal string) string
-// cnf.DefaultStrings(key string, defaultVal []string) []string
-// cnf.DefaultInt(key string, defaultVal int) int
-// cnf.DefaultInt64(key string, defaultVal int64) int64
-// cnf.DefaultBool(key string, defaultVal bool) bool
-// cnf.DefaultFloat(key string, defaultVal float64) float64
-// cnf.DIY(key string) (interface{}, error)
-// cnf.GetSection(section string) (map[string]string, error)
-// cnf.SaveConfigFile(filename string) error
-// More docs http://beego.me/docs/module/config.md
-package config
-
-import (
- "github.com/astaxie/beego/core/config"
-)
-
-// Configer defines how to get and set value from configuration raw data.
-type Configer interface {
- Set(key, val string) error // support section::key type in given key when using ini type.
- String(key string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
- Strings(key string) []string // get string slice
- Int(key string) (int, error)
- Int64(key string) (int64, error)
- Bool(key string) (bool, error)
- Float(key string) (float64, error)
- DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
- DefaultStrings(key string, defaultVal []string) []string // get string slice
- DefaultInt(key string, defaultVal int) int
- DefaultInt64(key string, defaultVal int64) int64
- DefaultBool(key string, defaultVal bool) bool
- DefaultFloat(key string, defaultVal float64) float64
- DIY(key string) (interface{}, error)
- GetSection(section string) (map[string]string, error)
- SaveConfigFile(filename string) error
-}
-
-// Config is the adapter interface for parsing config file to get raw data to Configer.
-type Config interface {
- Parse(key string) (Configer, error)
- ParseData(data []byte) (Configer, error)
-}
-
-var adapters = make(map[string]Config)
-
-// Register makes a config adapter available by the adapter name.
-// If Register is called twice with the same name or if driver is nil,
-// it panics.
-func Register(name string, adapter Config) {
- config.Register(name, &oldToNewConfigAdapter{delegate: adapter})
-}
-
-// NewConfig adapterName is ini/json/xml/yaml.
-// filename is the config file path.
-func NewConfig(adapterName, filename string) (Configer, error) {
- cfg, err := config.NewConfig(adapterName, filename)
- if err != nil {
- return nil, err
- }
-
- // it was registered by using Register method
- res, ok := cfg.(*oldToNewConfigerAdapter)
- if ok {
- return res.delegate, nil
- }
-
- return &newToOldConfigerAdapter{
- delegate: cfg,
- }, nil
-}
-
-// NewConfigData adapterName is ini/json/xml/yaml.
-// data is the config data.
-func NewConfigData(adapterName string, data []byte) (Configer, error) {
- cfg, err := config.NewConfigData(adapterName, data)
- if err != nil {
- return nil, err
- }
-
- // it was registered by using Register method
- res, ok := cfg.(*oldToNewConfigerAdapter)
- if ok {
- return res.delegate, nil
- }
-
- return &newToOldConfigerAdapter{
- delegate: cfg,
- }, nil
-}
-
-// ExpandValueEnvForMap convert all string value with environment variable.
-func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{} {
- return config.ExpandValueEnvForMap(m)
-}
-
-// ExpandValueEnv returns value of convert with environment variable.
-//
-// Return environment variable if value start with "${" and end with "}".
-// Return default value if environment variable is empty or not exist.
-//
-// It accept value formats "${env}" , "${env||}}" , "${env||defaultValue}" , "defaultvalue".
-// Examples:
-// v1 := config.ExpandValueEnv("${GOPATH}") // return the GOPATH environment variable.
-// v2 := config.ExpandValueEnv("${GOAsta||/usr/local/go}") // return the default value "/usr/local/go/".
-// v3 := config.ExpandValueEnv("Astaxie") // return the value "Astaxie".
-func ExpandValueEnv(value string) string {
- return config.ExpandValueEnv(value)
-}
-
-// ParseBool returns the boolean value represented by the string.
-//
-// It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on, On,
-// 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
-// Any other value returns an error.
-func ParseBool(val interface{}) (value bool, err error) {
- return config.ParseBool(val)
-}
-
-// ToString converts values of any type to string.
-func ToString(x interface{}) string {
- return config.ToString(x)
-}
diff --git a/adapter/config/env/env.go b/adapter/config/env/env.go
deleted file mode 100644
index 839c60c1..00000000
--- a/adapter/config/env/env.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-// Copyright 2017 Faissal Elamraoui. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package env is used to parse environment.
-package env
-
-import (
- "github.com/astaxie/beego/core/config/env"
-)
-
-// Get returns a value by key.
-// If the key does not exist, the default value will be returned.
-func Get(key string, defVal string) string {
- return env.Get(key, defVal)
-}
-
-// MustGet returns a value by key.
-// If the key does not exist, it will return an error.
-func MustGet(key string) (string, error) {
- return env.MustGet(key)
-}
-
-// Set sets a value in the ENV copy.
-// This does not affect the child process environment.
-func Set(key string, value string) {
- env.Set(key, value)
-}
-
-// MustSet sets a value in the ENV copy and the child process environment.
-// It returns an error in case the set operation failed.
-func MustSet(key string, value string) error {
- return env.MustSet(key, value)
-}
-
-// GetAll returns all keys/values in the current child process environment.
-func GetAll() map[string]string {
- return env.GetAll()
-}
diff --git a/adapter/config/fake.go b/adapter/config/fake.go
deleted file mode 100644
index 050f0252..00000000
--- a/adapter/config/fake.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package config
-
-import (
- "github.com/astaxie/beego/core/config"
-)
-
-// NewFakeConfig return a fake Configer
-func NewFakeConfig() Configer {
- new := config.NewFakeConfig()
- return &newToOldConfigerAdapter{delegate: new}
-}
diff --git a/adapter/config/xml/xml.go b/adapter/config/xml/xml.go
deleted file mode 100644
index 28d5f44e..00000000
--- a/adapter/config/xml/xml.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package xml for config provider.
-//
-// depend on github.com/beego/x2j.
-//
-// go install github.com/beego/x2j.
-//
-// Usage:
-// import(
-// _ "github.com/astaxie/beego/config/xml"
-// "github.com/astaxie/beego/config"
-// )
-//
-// cnf, err := config.NewConfig("xml", "config.xml")
-//
-// More docs http://beego.me/docs/module/config.md
-package xml
-
-import (
- _ "github.com/astaxie/beego/core/config/xml"
-)
diff --git a/adapter/config/yaml/yaml.go b/adapter/config/yaml/yaml.go
deleted file mode 100644
index 196c9725..00000000
--- a/adapter/config/yaml/yaml.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package yaml for config provider
-//
-// depend on github.com/beego/goyaml2
-//
-// go install github.com/beego/goyaml2
-//
-// Usage:
-// import(
-// _ "github.com/astaxie/beego/config/yaml"
-// "github.com/astaxie/beego/config"
-// )
-//
-// cnf, err := config.NewConfig("yaml", "config.yaml")
-//
-// More docs http://beego.me/docs/module/config.md
-package yaml
-
-import (
- _ "github.com/astaxie/beego/core/config/yaml"
-)
diff --git a/adapter/context/acceptencoder.go b/adapter/context/acceptencoder.go
deleted file mode 100644
index 4bfef95e..00000000
--- a/adapter/context/acceptencoder.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package context
-
-import (
- "io"
- "net/http"
- "os"
-
- "github.com/astaxie/beego/server/web/context"
-)
-
-// InitGzip init the gzipcompress
-func InitGzip(minLength, compressLevel int, methods []string) {
- context.InitGzip(minLength, compressLevel, methods)
-}
-
-// WriteFile reads from file and writes to writer by the specific encoding(gzip/deflate)
-func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string, error) {
- return context.WriteFile(encoding, writer, file)
-}
-
-// WriteBody reads writes content to writer by the specific encoding(gzip/deflate)
-func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string, error) {
- return context.WriteBody(encoding, writer, content)
-}
-
-// ParseEncoding will extract the right encoding for response
-// the Accept-Encoding's sec is here:
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
-func ParseEncoding(r *http.Request) string {
- return context.ParseEncoding(r)
-}
diff --git a/adapter/context/context.go b/adapter/context/context.go
deleted file mode 100644
index 123fdb2c..00000000
--- a/adapter/context/context.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package context provide the context utils
-// Usage:
-//
-// import "github.com/astaxie/beego/context"
-//
-// ctx := context.Context{Request:req,ResponseWriter:rw}
-//
-// more docs http://beego.me/docs/module/context.md
-package context
-
-import (
- "bufio"
- "net"
- "net/http"
-
- "github.com/astaxie/beego/server/web/context"
-)
-
-// commonly used mime-types
-const (
- ApplicationJSON = context.ApplicationJSON
- ApplicationXML = context.ApplicationXML
- ApplicationYAML = context.ApplicationYAML
- TextXML = context.TextXML
-)
-
-// NewContext return the Context with Input and Output
-func NewContext() *Context {
- return (*Context)(context.NewContext())
-}
-
-// Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
-// BeegoInput and BeegoOutput provides some api to operate request and response more easily.
-type Context context.Context
-
-// Reset init Context, BeegoInput and BeegoOutput
-func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
- (*context.Context)(ctx).Reset(rw, r)
-}
-
-// Redirect does redirection to localurl with http header status code.
-func (ctx *Context) Redirect(status int, localurl string) {
- (*context.Context)(ctx).Redirect(status, localurl)
-}
-
-// Abort stops this request.
-// if beego.ErrorMaps exists, panic body.
-func (ctx *Context) Abort(status int, body string) {
- (*context.Context)(ctx).Abort(status, body)
-}
-
-// WriteString Write string to response body.
-// it sends response body.
-func (ctx *Context) WriteString(content string) {
- (*context.Context)(ctx).WriteString(content)
-}
-
-// GetCookie Get cookie from request by a given key.
-// It's alias of BeegoInput.Cookie.
-func (ctx *Context) GetCookie(key string) string {
- return (*context.Context)(ctx).GetCookie(key)
-}
-
-// SetCookie Set cookie for response.
-// It's alias of BeegoOutput.Cookie.
-func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
- (*context.Context)(ctx).SetCookie(name, value, others)
-}
-
-// GetSecureCookie Get secure cookie from request by a given key.
-func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
- return (*context.Context)(ctx).GetSecureCookie(Secret, key)
-}
-
-// SetSecureCookie Set Secure cookie for response.
-func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
- (*context.Context)(ctx).SetSecureCookie(Secret, name, value, others)
-}
-
-// XSRFToken creates a xsrf token string and returns.
-func (ctx *Context) XSRFToken(key string, expire int64) string {
- return (*context.Context)(ctx).XSRFToken(key, expire)
-}
-
-// CheckXSRFCookie checks xsrf token in this request is valid or not.
-// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
-// or in form field value named as "_xsrf".
-func (ctx *Context) CheckXSRFCookie() bool {
- return (*context.Context)(ctx).CheckXSRFCookie()
-}
-
-// RenderMethodResult renders the return value of a controller method to the output
-func (ctx *Context) RenderMethodResult(result interface{}) {
- (*context.Context)(ctx).RenderMethodResult(result)
-}
-
-// Response is a wrapper for the http.ResponseWriter
-// started set to true if response was written to then don't execute other handler
-type Response context.Response
-
-// Write writes the data to the connection as part of an HTTP reply,
-// and sets `started` to true.
-// started means the response has sent out.
-func (r *Response) Write(p []byte) (int, error) {
- return (*context.Response)(r).Write(p)
-}
-
-// WriteHeader sends an HTTP response header with status code,
-// and sets `started` to true.
-func (r *Response) WriteHeader(code int) {
- (*context.Response)(r).WriteHeader(code)
-}
-
-// Hijack hijacker for http
-func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- return (*context.Response)(r).Hijack()
-}
-
-// Flush http.Flusher
-func (r *Response) Flush() {
- (*context.Response)(r).Flush()
-}
-
-// CloseNotify http.CloseNotifier
-func (r *Response) CloseNotify() <-chan bool {
- return (*context.Response)(r).CloseNotify()
-}
-
-// Pusher http.Pusher
-func (r *Response) Pusher() (pusher http.Pusher) {
- return (*context.Response)(r).Pusher()
-}
diff --git a/adapter/context/input.go b/adapter/context/input.go
deleted file mode 100644
index 51bb9ea5..00000000
--- a/adapter/context/input.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package context
-
-import (
- "github.com/astaxie/beego/server/web/context"
-)
-
-// BeegoInput operates the http request header, data, cookie and body.
-// it also contains router params and current session.
-type BeegoInput context.BeegoInput
-
-// NewInput return BeegoInput generated by Context.
-func NewInput() *BeegoInput {
- return (*BeegoInput)(context.NewInput())
-}
-
-// Reset init the BeegoInput
-func (input *BeegoInput) Reset(ctx *Context) {
- (*context.BeegoInput)(input).Reset((*context.Context)(ctx))
-}
-
-// Protocol returns request protocol name, such as HTTP/1.1 .
-func (input *BeegoInput) Protocol() string {
- return (*context.BeegoInput)(input).Protocol()
-}
-
-// URI returns full request url with query string, fragment.
-func (input *BeegoInput) URI() string {
- return input.Context.Request.RequestURI
-}
-
-// URL returns request url path (without query string, fragment).
-func (input *BeegoInput) URL() string {
- return (*context.BeegoInput)(input).URL()
-}
-
-// Site returns base site url as scheme://domain type.
-func (input *BeegoInput) Site() string {
- return (*context.BeegoInput)(input).Site()
-}
-
-// Scheme returns request scheme as "http" or "https".
-func (input *BeegoInput) Scheme() string {
- return (*context.BeegoInput)(input).Scheme()
-}
-
-// Domain returns host name.
-// Alias of Host method.
-func (input *BeegoInput) Domain() string {
- return (*context.BeegoInput)(input).Domain()
-}
-
-// Host returns host name.
-// if no host info in request, return localhost.
-func (input *BeegoInput) Host() string {
- return (*context.BeegoInput)(input).Host()
-}
-
-// Method returns http request method.
-func (input *BeegoInput) Method() string {
- return (*context.BeegoInput)(input).Method()
-}
-
-// Is returns boolean of this request is on given method, such as Is("POST").
-func (input *BeegoInput) Is(method string) bool {
- return (*context.BeegoInput)(input).Is(method)
-}
-
-// IsGet Is this a GET method request?
-func (input *BeegoInput) IsGet() bool {
- return (*context.BeegoInput)(input).IsGet()
-}
-
-// IsPost Is this a POST method request?
-func (input *BeegoInput) IsPost() bool {
- return (*context.BeegoInput)(input).IsPost()
-}
-
-// IsHead Is this a Head method request?
-func (input *BeegoInput) IsHead() bool {
- return (*context.BeegoInput)(input).IsHead()
-}
-
-// IsOptions Is this a OPTIONS method request?
-func (input *BeegoInput) IsOptions() bool {
- return (*context.BeegoInput)(input).IsOptions()
-}
-
-// IsPut Is this a PUT method request?
-func (input *BeegoInput) IsPut() bool {
- return (*context.BeegoInput)(input).IsPut()
-}
-
-// IsDelete Is this a DELETE method request?
-func (input *BeegoInput) IsDelete() bool {
- return (*context.BeegoInput)(input).IsDelete()
-}
-
-// IsPatch Is this a PATCH method request?
-func (input *BeegoInput) IsPatch() bool {
- return (*context.BeegoInput)(input).IsPatch()
-}
-
-// IsAjax returns boolean of this request is generated by ajax.
-func (input *BeegoInput) IsAjax() bool {
- return (*context.BeegoInput)(input).IsAjax()
-}
-
-// IsSecure returns boolean of this request is in https.
-func (input *BeegoInput) IsSecure() bool {
- return (*context.BeegoInput)(input).IsSecure()
-}
-
-// IsWebsocket returns boolean of this request is in webSocket.
-func (input *BeegoInput) IsWebsocket() bool {
- return (*context.BeegoInput)(input).IsWebsocket()
-}
-
-// IsUpload returns boolean of whether file uploads in this request or not..
-func (input *BeegoInput) IsUpload() bool {
- return (*context.BeegoInput)(input).IsUpload()
-}
-
-// AcceptsHTML Checks if request accepts html response
-func (input *BeegoInput) AcceptsHTML() bool {
- return (*context.BeegoInput)(input).AcceptsHTML()
-}
-
-// AcceptsXML Checks if request accepts xml response
-func (input *BeegoInput) AcceptsXML() bool {
- return (*context.BeegoInput)(input).AcceptsXML()
-}
-
-// AcceptsJSON Checks if request accepts json response
-func (input *BeegoInput) AcceptsJSON() bool {
- return (*context.BeegoInput)(input).AcceptsJSON()
-}
-
-// AcceptsYAML Checks if request accepts json response
-func (input *BeegoInput) AcceptsYAML() bool {
- return (*context.BeegoInput)(input).AcceptsYAML()
-}
-
-// IP returns request client ip.
-// if in proxy, return first proxy id.
-// if error, return RemoteAddr.
-func (input *BeegoInput) IP() string {
- return (*context.BeegoInput)(input).IP()
-}
-
-// Proxy returns proxy client ips slice.
-func (input *BeegoInput) Proxy() []string {
- return (*context.BeegoInput)(input).Proxy()
-}
-
-// Referer returns http referer header.
-func (input *BeegoInput) Referer() string {
- return (*context.BeegoInput)(input).Referer()
-}
-
-// Refer returns http referer header.
-func (input *BeegoInput) Refer() string {
- return (*context.BeegoInput)(input).Refer()
-}
-
-// SubDomains returns sub domain string.
-// if aa.bb.domain.com, returns aa.bb .
-func (input *BeegoInput) SubDomains() string {
- return (*context.BeegoInput)(input).SubDomains()
-}
-
-// Port returns request client port.
-// when error or empty, return 80.
-func (input *BeegoInput) Port() int {
- return (*context.BeegoInput)(input).Port()
-}
-
-// UserAgent returns request client user agent string.
-func (input *BeegoInput) UserAgent() string {
- return (*context.BeegoInput)(input).UserAgent()
-}
-
-// ParamsLen return the length of the params
-func (input *BeegoInput) ParamsLen() int {
- return (*context.BeegoInput)(input).ParamsLen()
-}
-
-// Param returns router param by a given key.
-func (input *BeegoInput) Param(key string) string {
- return (*context.BeegoInput)(input).Param(key)
-}
-
-// Params returns the map[key]value.
-func (input *BeegoInput) Params() map[string]string {
- return (*context.BeegoInput)(input).Params()
-}
-
-// SetParam will set the param with key and value
-func (input *BeegoInput) SetParam(key, val string) {
- (*context.BeegoInput)(input).SetParam(key, val)
-}
-
-// ResetParams clears any of the input's Params
-// This function is used to clear parameters so they may be reset between filter
-// passes.
-func (input *BeegoInput) ResetParams() {
- (*context.BeegoInput)(input).ResetParams()
-}
-
-// Query returns input data item string by a given string.
-func (input *BeegoInput) Query(key string) string {
- return (*context.BeegoInput)(input).Query(key)
-}
-
-// Header returns request header item string by a given string.
-// if non-existed, return empty string.
-func (input *BeegoInput) Header(key string) string {
- return (*context.BeegoInput)(input).Header(key)
-}
-
-// Cookie returns request cookie item string by a given key.
-// if non-existed, return empty string.
-func (input *BeegoInput) Cookie(key string) string {
- return (*context.BeegoInput)(input).Cookie(key)
-}
-
-// Session returns current session item value by a given key.
-// if non-existed, return nil.
-func (input *BeegoInput) Session(key interface{}) interface{} {
- return (*context.BeegoInput)(input).Session(key)
-}
-
-// CopyBody returns the raw request body data as bytes.
-func (input *BeegoInput) CopyBody(MaxMemory int64) []byte {
- return (*context.BeegoInput)(input).CopyBody(MaxMemory)
-}
-
-// Data return the implicit data in the input
-func (input *BeegoInput) Data() map[interface{}]interface{} {
- return (*context.BeegoInput)(input).Data()
-}
-
-// GetData returns the stored data in this context.
-func (input *BeegoInput) GetData(key interface{}) interface{} {
- return (*context.BeegoInput)(input).GetData(key)
-}
-
-// SetData stores data with given key in this context.
-// This data are only available in this context.
-func (input *BeegoInput) SetData(key, val interface{}) {
- (*context.BeegoInput)(input).SetData(key, val)
-}
-
-// ParseFormOrMulitForm parseForm or parseMultiForm based on Content-type
-func (input *BeegoInput) ParseFormOrMulitForm(maxMemory int64) error {
- return (*context.BeegoInput)(input).ParseFormOrMultiForm(maxMemory)
-}
-
-// Bind data from request.Form[key] to dest
-// like /?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie
-// var id int beegoInput.Bind(&id, "id") id ==123
-// var isok bool beegoInput.Bind(&isok, "isok") isok ==true
-// var ft float64 beegoInput.Bind(&ft, "ft") ft ==1.2
-// ol := make([]int, 0, 2) beegoInput.Bind(&ol, "ol") ol ==[1 2]
-// ul := make([]string, 0, 2) beegoInput.Bind(&ul, "ul") ul ==[str array]
-// user struct{Name} beegoInput.Bind(&user, "user") user == {Name:"astaxie"}
-func (input *BeegoInput) Bind(dest interface{}, key string) error {
- return (*context.BeegoInput)(input).Bind(dest, key)
-}
diff --git a/adapter/context/output.go b/adapter/context/output.go
deleted file mode 100644
index 0223679b..00000000
--- a/adapter/context/output.go
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package context
-
-import (
- "github.com/astaxie/beego/server/web/context"
-)
-
-// BeegoOutput does work for sending response header.
-type BeegoOutput context.BeegoOutput
-
-// NewOutput returns new BeegoOutput.
-// it contains nothing now.
-func NewOutput() *BeegoOutput {
- return (*BeegoOutput)(context.NewOutput())
-}
-
-// Reset init BeegoOutput
-func (output *BeegoOutput) Reset(ctx *Context) {
- (*context.BeegoOutput)(output).Reset((*context.Context)(ctx))
-}
-
-// Header sets response header item string via given key.
-func (output *BeegoOutput) Header(key, val string) {
- (*context.BeegoOutput)(output).Header(key, val)
-}
-
-// Body sets response body content.
-// if EnableGzip, compress content string.
-// it sends out response body directly.
-func (output *BeegoOutput) Body(content []byte) error {
- return (*context.BeegoOutput)(output).Body(content)
-}
-
-// Cookie sets cookie value via given key.
-// others are ordered as cookie's max age time, path,domain, secure and httponly.
-func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
- (*context.BeegoOutput)(output).Cookie(name, value, others)
-}
-
-// JSON writes json to response body.
-// if encoding is true, it converts utf-8 to \u0000 type.
-func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
- return (*context.BeegoOutput)(output).JSON(data, hasIndent, encoding)
-}
-
-// YAML writes yaml to response body.
-func (output *BeegoOutput) YAML(data interface{}) error {
- return (*context.BeegoOutput)(output).YAML(data)
-}
-
-// JSONP writes jsonp to response body.
-func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
- return (*context.BeegoOutput)(output).JSONP(data, hasIndent)
-}
-
-// XML writes xml string to response body.
-func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
- return (*context.BeegoOutput)(output).XML(data, hasIndent)
-}
-
-// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
-func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
- (*context.BeegoOutput)(output).ServeFormatted(data, hasIndent, hasEncode...)
-}
-
-// Download forces response for download file.
-// it prepares the download response header automatically.
-func (output *BeegoOutput) Download(file string, filename ...string) {
- (*context.BeegoOutput)(output).Download(file, filename...)
-}
-
-// ContentType sets the content type from ext string.
-// MIME type is given in mime package.
-func (output *BeegoOutput) ContentType(ext string) {
- (*context.BeegoOutput)(output).ContentType(ext)
-}
-
-// SetStatus sets response status code.
-// It writes response header directly.
-func (output *BeegoOutput) SetStatus(status int) {
- (*context.BeegoOutput)(output).SetStatus(status)
-}
-
-// IsCachable returns boolean of this request is cached.
-// HTTP 304 means cached.
-func (output *BeegoOutput) IsCachable() bool {
- return (*context.BeegoOutput)(output).IsCachable()
-}
-
-// IsEmpty returns boolean of this request is empty.
-// HTTP 201,204 and 304 means empty.
-func (output *BeegoOutput) IsEmpty() bool {
- return (*context.BeegoOutput)(output).IsEmpty()
-}
-
-// IsOk returns boolean of this request runs well.
-// HTTP 200 means ok.
-func (output *BeegoOutput) IsOk() bool {
- return (*context.BeegoOutput)(output).IsOk()
-}
-
-// IsSuccessful returns boolean of this request runs successfully.
-// HTTP 2xx means ok.
-func (output *BeegoOutput) IsSuccessful() bool {
- return (*context.BeegoOutput)(output).IsSuccessful()
-}
-
-// IsRedirect returns boolean of this request is redirection header.
-// HTTP 301,302,307 means redirection.
-func (output *BeegoOutput) IsRedirect() bool {
- return (*context.BeegoOutput)(output).IsRedirect()
-}
-
-// IsForbidden returns boolean of this request is forbidden.
-// HTTP 403 means forbidden.
-func (output *BeegoOutput) IsForbidden() bool {
- return (*context.BeegoOutput)(output).IsForbidden()
-}
-
-// IsNotFound returns boolean of this request is not found.
-// HTTP 404 means not found.
-func (output *BeegoOutput) IsNotFound() bool {
- return (*context.BeegoOutput)(output).IsNotFound()
-}
-
-// IsClientError returns boolean of this request client sends error data.
-// HTTP 4xx means client error.
-func (output *BeegoOutput) IsClientError() bool {
- return (*context.BeegoOutput)(output).IsClientError()
-}
-
-// IsServerError returns boolean of this server handler errors.
-// HTTP 5xx means server internal error.
-func (output *BeegoOutput) IsServerError() bool {
- return (*context.BeegoOutput)(output).IsServerError()
-}
-
-// Session sets session item value with given key.
-func (output *BeegoOutput) Session(name interface{}, value interface{}) {
- (*context.BeegoOutput)(output).Session(name, value)
-}
diff --git a/adapter/context/renderer.go b/adapter/context/renderer.go
deleted file mode 100644
index 1309365a..00000000
--- a/adapter/context/renderer.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package context
-
-import (
- "github.com/astaxie/beego/server/web/context"
-)
-
-// Renderer defines an http response renderer
-type Renderer context.Renderer
diff --git a/adapter/controller.go b/adapter/controller.go
deleted file mode 100644
index 14dc9b97..00000000
--- a/adapter/controller.go
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
- "mime/multipart"
- "net/url"
-
- "github.com/astaxie/beego/adapter/session"
- webContext "github.com/astaxie/beego/server/web/context"
-
- "github.com/astaxie/beego/server/web"
-)
-
-var (
- // ErrAbort custom error when user stop request handler manually.
- ErrAbort = web.ErrAbort
- // GlobalControllerRouter store comments with controller. pkgpath+controller:comments
- GlobalControllerRouter = web.GlobalControllerRouter
-)
-
-// ControllerFilter store the filter for controller
-type ControllerFilter web.ControllerFilter
-
-// ControllerFilterComments store the comment for controller level filter
-type ControllerFilterComments web.ControllerFilterComments
-
-// ControllerImportComments store the import comment for controller needed
-type ControllerImportComments web.ControllerImportComments
-
-// ControllerComments store the comment for the controller method
-type ControllerComments web.ControllerComments
-
-// ControllerCommentsSlice implements the sort interface
-type ControllerCommentsSlice web.ControllerCommentsSlice
-
-func (p ControllerCommentsSlice) Len() int {
- return (web.ControllerCommentsSlice)(p).Len()
-}
-func (p ControllerCommentsSlice) Less(i, j int) bool {
- return (web.ControllerCommentsSlice)(p).Less(i, j)
-}
-func (p ControllerCommentsSlice) Swap(i, j int) {
- (web.ControllerCommentsSlice)(p).Swap(i, j)
-}
-
-// Controller defines some basic http request handler operations, such as
-// http context, template and view, session and xsrf.
-type Controller web.Controller
-
-func (c *Controller) Init(ctx *webContext.Context, controllerName, actionName string, app interface{}) {
- (*web.Controller)(c).Init(ctx, controllerName, actionName, app)
-}
-
-// ControllerInterface is an interface to uniform all controller handler.
-type ControllerInterface web.ControllerInterface
-
-// Prepare runs after Init before request function execution.
-func (c *Controller) Prepare() {
- (*web.Controller)(c).Prepare()
-}
-
-// Finish runs after request function execution.
-func (c *Controller) Finish() {
- (*web.Controller)(c).Finish()
-}
-
-// Get adds a request function to handle GET request.
-func (c *Controller) Get() {
- (*web.Controller)(c).Get()
-}
-
-// Post adds a request function to handle POST request.
-func (c *Controller) Post() {
- (*web.Controller)(c).Post()
-}
-
-// Delete adds a request function to handle DELETE request.
-func (c *Controller) Delete() {
- (*web.Controller)(c).Delete()
-}
-
-// Put adds a request function to handle PUT request.
-func (c *Controller) Put() {
- (*web.Controller)(c).Put()
-}
-
-// Head adds a request function to handle HEAD request.
-func (c *Controller) Head() {
- (*web.Controller)(c).Head()
-}
-
-// Patch adds a request function to handle PATCH request.
-func (c *Controller) Patch() {
- (*web.Controller)(c).Patch()
-}
-
-// Options adds a request function to handle OPTIONS request.
-func (c *Controller) Options() {
- (*web.Controller)(c).Options()
-}
-
-// Trace adds a request function to handle Trace request.
-// this method SHOULD NOT be overridden.
-// https://tools.ietf.org/html/rfc7231#section-4.3.8
-// The TRACE method requests a remote, application-level loop-back of
-// the request message. The final recipient of the request SHOULD
-// reflect the message received, excluding some fields described below,
-// back to the client as the message body of a 200 (OK) response with a
-// Content-Type of "message/http" (Section 8.3.1 of [RFC7230]).
-func (c *Controller) Trace() {
- (*web.Controller)(c).Trace()
-}
-
-// HandlerFunc call function with the name
-func (c *Controller) HandlerFunc(fnname string) bool {
- return (*web.Controller)(c).HandlerFunc(fnname)
-}
-
-// URLMapping register the internal Controller router.
-func (c *Controller) URLMapping() {
- (*web.Controller)(c).URLMapping()
-}
-
-// Mapping the method to function
-func (c *Controller) Mapping(method string, fn func()) {
- (*web.Controller)(c).Mapping(method, fn)
-}
-
-// Render sends the response with rendered template bytes as text/html type.
-func (c *Controller) Render() error {
- return (*web.Controller)(c).Render()
-}
-
-// RenderString returns the rendered template string. Do not send out response.
-func (c *Controller) RenderString() (string, error) {
- return (*web.Controller)(c).RenderString()
-}
-
-// RenderBytes returns the bytes of rendered template string. Do not send out response.
-func (c *Controller) RenderBytes() ([]byte, error) {
- return (*web.Controller)(c).RenderBytes()
-}
-
-// Redirect sends the redirection response to url with status code.
-func (c *Controller) Redirect(url string, code int) {
- (*web.Controller)(c).Redirect(url, code)
-}
-
-// SetData set the data depending on the accepted
-func (c *Controller) SetData(data interface{}) {
- (*web.Controller)(c).SetData(data)
-}
-
-// Abort stops controller handler and show the error data if code is defined in ErrorMap or code string.
-func (c *Controller) Abort(code string) {
- (*web.Controller)(c).Abort(code)
-}
-
-// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
-func (c *Controller) CustomAbort(status int, body string) {
- (*web.Controller)(c).CustomAbort(status, body)
-}
-
-// StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
-func (c *Controller) StopRun() {
- (*web.Controller)(c).StopRun()
-}
-
-// URLFor does another controller handler in this request function.
-// it goes to this controller method if endpoint is not clear.
-func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
- return (*web.Controller)(c).URLFor(endpoint, values...)
-}
-
-// ServeJSON sends a json response with encoding charset.
-func (c *Controller) ServeJSON(encoding ...bool) {
- (*web.Controller)(c).ServeJSON(encoding...)
-}
-
-// ServeJSONP sends a jsonp response.
-func (c *Controller) ServeJSONP() {
- (*web.Controller)(c).ServeJSONP()
-}
-
-// ServeXML sends xml response.
-func (c *Controller) ServeXML() {
- (*web.Controller)(c).ServeXML()
-}
-
-// ServeYAML sends yaml response.
-func (c *Controller) ServeYAML() {
- (*web.Controller)(c).ServeYAML()
-}
-
-// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
-func (c *Controller) ServeFormatted(encoding ...bool) {
- (*web.Controller)(c).ServeFormatted(encoding...)
-}
-
-// Input returns the input data map from POST or PUT request body and query string.
-func (c *Controller) Input() url.Values {
- return (*web.Controller)(c).Input()
-}
-
-// ParseForm maps input data map to obj struct.
-func (c *Controller) ParseForm(obj interface{}) error {
- return (*web.Controller)(c).ParseForm(obj)
-}
-
-// GetString returns the input value by key string or the default value while it's present and input is blank
-func (c *Controller) GetString(key string, def ...string) string {
- return (*web.Controller)(c).GetString(key, def...)
-}
-
-// GetStrings returns the input string slice by key string or the default value while it's present and input is blank
-// it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
-func (c *Controller) GetStrings(key string, def ...[]string) []string {
- return (*web.Controller)(c).GetStrings(key, def...)
-}
-
-// GetInt returns input as an int or the default value while it's present and input is blank
-func (c *Controller) GetInt(key string, def ...int) (int, error) {
- return (*web.Controller)(c).GetInt(key, def...)
-}
-
-// GetInt8 return input as an int8 or the default value while it's present and input is blank
-func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
- return (*web.Controller)(c).GetInt8(key, def...)
-}
-
-// GetUint8 return input as an uint8 or the default value while it's present and input is blank
-func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
- return (*web.Controller)(c).GetUint8(key, def...)
-}
-
-// GetInt16 returns input as an int16 or the default value while it's present and input is blank
-func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
- return (*web.Controller)(c).GetInt16(key, def...)
-}
-
-// GetUint16 returns input as an uint16 or the default value while it's present and input is blank
-func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
- return (*web.Controller)(c).GetUint16(key, def...)
-}
-
-// GetInt32 returns input as an int32 or the default value while it's present and input is blank
-func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
- return (*web.Controller)(c).GetInt32(key, def...)
-}
-
-// GetUint32 returns input as an uint32 or the default value while it's present and input is blank
-func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
- return (*web.Controller)(c).GetUint32(key, def...)
-}
-
-// GetInt64 returns input value as int64 or the default value while it's present and input is blank.
-func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
- return (*web.Controller)(c).GetInt64(key, def...)
-}
-
-// GetUint64 returns input value as uint64 or the default value while it's present and input is blank.
-func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
- return (*web.Controller)(c).GetUint64(key, def...)
-}
-
-// GetBool returns input value as bool or the default value while it's present and input is blank.
-func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
- return (*web.Controller)(c).GetBool(key, def...)
-}
-
-// GetFloat returns input value as float64 or the default value while it's present and input is blank.
-func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
- return (*web.Controller)(c).GetFloat(key, def...)
-}
-
-// GetFile returns the file data in file upload field named as key.
-// it returns the first one of multi-uploaded files.
-func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
- return (*web.Controller)(c).GetFile(key)
-}
-
-// GetFiles return multi-upload files
-// files, err:=c.GetFiles("myfiles")
-// if err != nil {
-// http.Error(w, err.Error(), http.StatusNoContent)
-// return
-// }
-// for i, _ := range files {
-// //for each fileheader, get a handle to the actual file
-// file, err := files[i].Open()
-// defer file.Close()
-// if err != nil {
-// http.Error(w, err.Error(), http.StatusInternalServerError)
-// return
-// }
-// //create destination file making sure the path is writeable.
-// dst, err := os.Create("upload/" + files[i].Filename)
-// defer dst.Close()
-// if err != nil {
-// http.Error(w, err.Error(), http.StatusInternalServerError)
-// return
-// }
-// //copy the uploaded file to the destination file
-// if _, err := io.Copy(dst, file); err != nil {
-// http.Error(w, err.Error(), http.StatusInternalServerError)
-// return
-// }
-// }
-func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
- return (*web.Controller)(c).GetFiles(key)
-}
-
-// SaveToFile saves uploaded file to new path.
-// it only operates the first one of mutil-upload form file field.
-func (c *Controller) SaveToFile(fromfile, tofile string) error {
- return (*web.Controller)(c).SaveToFile(fromfile, tofile)
-}
-
-// StartSession starts session and load old session data info this controller.
-func (c *Controller) StartSession() session.Store {
- s := (*web.Controller)(c).StartSession()
- return session.CreateNewToOldStoreAdapter(s)
-}
-
-// SetSession puts value into session.
-func (c *Controller) SetSession(name interface{}, value interface{}) {
- (*web.Controller)(c).SetSession(name, value)
-}
-
-// GetSession gets value from session.
-func (c *Controller) GetSession(name interface{}) interface{} {
- return (*web.Controller)(c).GetSession(name)
-}
-
-// DelSession removes value from session.
-func (c *Controller) DelSession(name interface{}) {
- (*web.Controller)(c).DelSession(name)
-}
-
-// SessionRegenerateID regenerates session id for this session.
-// the session data have no changes.
-func (c *Controller) SessionRegenerateID() {
- (*web.Controller)(c).SessionRegenerateID()
-}
-
-// DestroySession cleans session data and session cookie.
-func (c *Controller) DestroySession() {
- (*web.Controller)(c).DestroySession()
-}
-
-// IsAjax returns this request is ajax or not.
-func (c *Controller) IsAjax() bool {
- return (*web.Controller)(c).IsAjax()
-}
-
-// GetSecureCookie returns decoded cookie value from encoded browser cookie values.
-func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
- return (*web.Controller)(c).GetSecureCookie(Secret, key)
-}
-
-// SetSecureCookie puts value into cookie after encoded the value.
-func (c *Controller) SetSecureCookie(Secret, name, value string, others ...interface{}) {
- (*web.Controller)(c).SetSecureCookie(Secret, name, value, others...)
-}
-
-// XSRFToken creates a CSRF token string and returns.
-func (c *Controller) XSRFToken() string {
- return (*web.Controller)(c).XSRFToken()
-}
-
-// CheckXSRFCookie checks xsrf token in this request is valid or not.
-// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
-// or in form field value named as "_xsrf".
-func (c *Controller) CheckXSRFCookie() bool {
- return (*web.Controller)(c).CheckXSRFCookie()
-}
-
-// XSRFFormHTML writes an input field contains xsrf token value.
-func (c *Controller) XSRFFormHTML() string {
- return (*web.Controller)(c).XSRFFormHTML()
-}
-
-// GetControllerAndAction gets the executing controller name and action name.
-func (c *Controller) GetControllerAndAction() (string, string) {
- return (*web.Controller)(c).GetControllerAndAction()
-}
diff --git a/adapter/doc.go b/adapter/doc.go
deleted file mode 100644
index c8f2174c..00000000
--- a/adapter/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// used to keep compatible with v1.x
-package adapter
diff --git a/adapter/error.go b/adapter/error.go
deleted file mode 100644
index 35ff7f35..00000000
--- a/adapter/error.go
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
- "net/http"
-
- "github.com/astaxie/beego/adapter/context"
- beecontext "github.com/astaxie/beego/server/web/context"
-
- "github.com/astaxie/beego/server/web"
-)
-
-const (
- errorTypeHandler = iota
- errorTypeController
-)
-
-var tpl = `
-
-
-
-
- beego application error
-
-
-
-
-
- {{end}}
-
-See also
-
-http://beego.me/docs/mvc/view/page.md
-
-*/
-package pagination
diff --git a/core/utils/rand_test.go b/core/utils/rand_test.go
deleted file mode 100644
index 6c238b5e..00000000
--- a/core/utils/rand_test.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package utils
-
-import "testing"
-
-func TestRand_01(t *testing.T) {
- bs0 := RandomCreateBytes(16)
- bs1 := RandomCreateBytes(16)
-
- t.Log(string(bs0), string(bs1))
- if string(bs0) == string(bs1) {
- t.FailNow()
- }
-
- bs0 = RandomCreateBytes(4, []byte(`a`)...)
-
- if string(bs0) != "aaaa" {
- t.FailNow()
- }
-}
diff --git a/core/utils/safemap_test.go b/core/utils/safemap_test.go
deleted file mode 100644
index 65085195..00000000
--- a/core/utils/safemap_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package utils
-
-import "testing"
-
-var safeMap *BeeMap
-
-func TestNewBeeMap(t *testing.T) {
- safeMap = NewBeeMap()
- if safeMap == nil {
- t.Fatal("expected to return non-nil BeeMap", "got", safeMap)
- }
-}
-
-func TestSet(t *testing.T) {
- safeMap = NewBeeMap()
- if ok := safeMap.Set("astaxie", 1); !ok {
- t.Error("expected", true, "got", false)
- }
-}
-
-func TestReSet(t *testing.T) {
- safeMap := NewBeeMap()
- if ok := safeMap.Set("astaxie", 1); !ok {
- t.Error("expected", true, "got", false)
- }
- // set diff value
- if ok := safeMap.Set("astaxie", -1); !ok {
- t.Error("expected", true, "got", false)
- }
-
- // set same value
- if ok := safeMap.Set("astaxie", -1); ok {
- t.Error("expected", false, "got", true)
- }
-}
-
-func TestCheck(t *testing.T) {
- if exists := safeMap.Check("astaxie"); !exists {
- t.Error("expected", true, "got", false)
- }
-}
-
-func TestGet(t *testing.T) {
- if val := safeMap.Get("astaxie"); val.(int) != 1 {
- t.Error("expected value", 1, "got", val)
- }
-}
-
-func TestDelete(t *testing.T) {
- safeMap.Delete("astaxie")
- if exists := safeMap.Check("astaxie"); exists {
- t.Error("expected element to be deleted")
- }
-}
-
-func TestItems(t *testing.T) {
- safeMap := NewBeeMap()
- safeMap.Set("astaxie", "hello")
- for k, v := range safeMap.Items() {
- key := k.(string)
- value := v.(string)
- if key != "astaxie" {
- t.Error("expected the key should be astaxie")
- }
- if value != "hello" {
- t.Error("expected the value should be hello")
- }
- }
-}
-
-func TestCount(t *testing.T) {
- if count := safeMap.Count(); count != 0 {
- t.Error("expected count to be", 0, "got", count)
- }
-}
diff --git a/core/utils/slice_test.go b/core/utils/slice_test.go
deleted file mode 100644
index 142dec96..00000000
--- a/core/utils/slice_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package utils
-
-import (
- "testing"
-)
-
-func TestInSlice(t *testing.T) {
- sl := []string{"A", "b"}
- if !InSlice("A", sl) {
- t.Error("should be true")
- }
- if InSlice("B", sl) {
- t.Error("should be false")
- }
-}
diff --git a/core/utils/time.go b/core/utils/time.go
deleted file mode 100644
index 579b292a..00000000
--- a/core/utils/time.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package utils
-
-import (
- "fmt"
- "time"
-)
-
-// short string format
-func ToShortTimeFormat(d time.Duration) string {
-
- u := uint64(d)
- if u < uint64(time.Second) {
- switch {
- case u == 0:
- return "0"
- case u < uint64(time.Microsecond):
- return fmt.Sprintf("%.2fns", float64(u))
- case u < uint64(time.Millisecond):
- return fmt.Sprintf("%.2fus", float64(u)/1000)
- default:
- return fmt.Sprintf("%.2fms", float64(u)/1000/1000)
- }
- } else {
- switch {
- case u < uint64(time.Minute):
- return fmt.Sprintf("%.2fs", float64(u)/1000/1000/1000)
- case u < uint64(time.Hour):
- return fmt.Sprintf("%.2fm", float64(u)/1000/1000/1000/60)
- default:
- return fmt.Sprintf("%.2fh", float64(u)/1000/1000/1000/60/60)
- }
- }
-
-}
diff --git a/core/validation/validation_test.go b/core/validation/validation_test.go
deleted file mode 100644
index bca4f560..00000000
--- a/core/validation/validation_test.go
+++ /dev/null
@@ -1,634 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package validation
-
-import (
- "regexp"
- "testing"
- "time"
-)
-
-func TestRequired(t *testing.T) {
- valid := Validation{}
-
- if valid.Required(nil, "nil").Ok {
- t.Error("nil object should be false")
- }
- if !valid.Required(true, "bool").Ok {
- t.Error("Bool value should always return true")
- }
- if !valid.Required(false, "bool").Ok {
- t.Error("Bool value should always return true")
- }
- if valid.Required("", "string").Ok {
- t.Error("\"'\" string should be false")
- }
- if valid.Required(" ", "string").Ok {
- t.Error("\" \" string should be false") // For #2361
- }
- if valid.Required("\n", "string").Ok {
- t.Error("new line string should be false") // For #2361
- }
- if !valid.Required("astaxie", "string").Ok {
- t.Error("string should be true")
- }
- if valid.Required(0, "zero").Ok {
- t.Error("Integer should not be equal 0")
- }
- if !valid.Required(1, "int").Ok {
- t.Error("Integer except 0 should be true")
- }
- if !valid.Required(time.Now(), "time").Ok {
- t.Error("time should be true")
- }
- if valid.Required([]string{}, "emptySlice").Ok {
- t.Error("empty slice should be false")
- }
- if !valid.Required([]interface{}{"ok"}, "slice").Ok {
- t.Error("slice should be true")
- }
-}
-
-func TestMin(t *testing.T) {
- valid := Validation{}
-
- if valid.Min(-1, 0, "min0").Ok {
- t.Error("-1 is less than the minimum value of 0 should be false")
- }
- if !valid.Min(1, 0, "min0").Ok {
- t.Error("1 is greater or equal than the minimum value of 0 should be true")
- }
-}
-
-func TestMax(t *testing.T) {
- valid := Validation{}
-
- if valid.Max(1, 0, "max0").Ok {
- t.Error("1 is greater than the minimum value of 0 should be false")
- }
- if !valid.Max(-1, 0, "max0").Ok {
- t.Error("-1 is less or equal than the maximum value of 0 should be true")
- }
-}
-
-func TestRange(t *testing.T) {
- valid := Validation{}
-
- if valid.Range(-1, 0, 1, "range0_1").Ok {
- t.Error("-1 is between 0 and 1 should be false")
- }
- if !valid.Range(1, 0, 1, "range0_1").Ok {
- t.Error("1 is between 0 and 1 should be true")
- }
-}
-
-func TestMinSize(t *testing.T) {
- valid := Validation{}
-
- if valid.MinSize("", 1, "minSize1").Ok {
- t.Error("the length of \"\" is less than the minimum value of 1 should be false")
- }
- if !valid.MinSize("ok", 1, "minSize1").Ok {
- t.Error("the length of \"ok\" is greater or equal than the minimum value of 1 should be true")
- }
- if valid.MinSize([]string{}, 1, "minSize1").Ok {
- t.Error("the length of empty slice is less than the minimum value of 1 should be false")
- }
- if !valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok {
- t.Error("the length of [\"ok\"] is greater or equal than the minimum value of 1 should be true")
- }
-}
-
-func TestMaxSize(t *testing.T) {
- valid := Validation{}
-
- if valid.MaxSize("ok", 1, "maxSize1").Ok {
- t.Error("the length of \"ok\" is greater than the maximum value of 1 should be false")
- }
- if !valid.MaxSize("", 1, "maxSize1").Ok {
- t.Error("the length of \"\" is less or equal than the maximum value of 1 should be true")
- }
- if valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok {
- t.Error("the length of [\"ok\", false] is greater than the maximum value of 1 should be false")
- }
- if !valid.MaxSize([]string{}, 1, "maxSize1").Ok {
- t.Error("the length of empty slice is less or equal than the maximum value of 1 should be true")
- }
-}
-
-func TestLength(t *testing.T) {
- valid := Validation{}
-
- if valid.Length("", 1, "length1").Ok {
- t.Error("the length of \"\" must equal 1 should be false")
- }
- if !valid.Length("1", 1, "length1").Ok {
- t.Error("the length of \"1\" must equal 1 should be true")
- }
- if valid.Length([]string{}, 1, "length1").Ok {
- t.Error("the length of empty slice must equal 1 should be false")
- }
- if !valid.Length([]interface{}{"ok"}, 1, "length1").Ok {
- t.Error("the length of [\"ok\"] must equal 1 should be true")
- }
-}
-
-func TestAlpha(t *testing.T) {
- valid := Validation{}
-
- if valid.Alpha("a,1-@ $", "alpha").Ok {
- t.Error("\"a,1-@ $\" are valid alpha characters should be false")
- }
- if !valid.Alpha("abCD", "alpha").Ok {
- t.Error("\"abCD\" are valid alpha characters should be true")
- }
-}
-
-func TestNumeric(t *testing.T) {
- valid := Validation{}
-
- if valid.Numeric("a,1-@ $", "numeric").Ok {
- t.Error("\"a,1-@ $\" are valid numeric characters should be false")
- }
- if !valid.Numeric("1234", "numeric").Ok {
- t.Error("\"1234\" are valid numeric characters should be true")
- }
-}
-
-func TestAlphaNumeric(t *testing.T) {
- valid := Validation{}
-
- if valid.AlphaNumeric("a,1-@ $", "alphaNumeric").Ok {
- t.Error("\"a,1-@ $\" are valid alpha or numeric characters should be false")
- }
- if !valid.AlphaNumeric("1234aB", "alphaNumeric").Ok {
- t.Error("\"1234aB\" are valid alpha or numeric characters should be true")
- }
-}
-
-func TestMatch(t *testing.T) {
- valid := Validation{}
-
- 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 {
- t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true")
- }
-}
-
-func TestNoMatch(t *testing.T) {
- valid := Validation{}
-
- 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 {
- t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true")
- }
-}
-
-func TestAlphaDash(t *testing.T) {
- valid := Validation{}
-
- if valid.AlphaDash("a,1-@ $", "alphaDash").Ok {
- t.Error("\"a,1-@ $\" are valid alpha or numeric or dash(-_) characters should be false")
- }
- if !valid.AlphaDash("1234aB-_", "alphaDash").Ok {
- t.Error("\"1234aB\" are valid alpha or numeric or dash(-_) characters should be true")
- }
-}
-
-func TestEmail(t *testing.T) {
- valid := Validation{}
-
- if valid.Email("not@a email", "email").Ok {
- t.Error("\"not@a email\" is a valid email address should be false")
- }
- if !valid.Email("suchuangji@gmail.com", "email").Ok {
- t.Error("\"suchuangji@gmail.com\" is a valid email address should be true")
- }
- if valid.Email("@suchuangji@gmail.com", "email").Ok {
- t.Error("\"@suchuangji@gmail.com\" is a valid email address should be false")
- }
- if valid.Email("suchuangji@gmail.com ok", "email").Ok {
- t.Error("\"suchuangji@gmail.com ok\" is a valid email address should be false")
- }
-}
-
-func TestIP(t *testing.T) {
- valid := Validation{}
-
- if valid.IP("11.255.255.256", "IP").Ok {
- t.Error("\"11.255.255.256\" is a valid ip address should be false")
- }
- if !valid.IP("01.11.11.11", "IP").Ok {
- t.Error("\"suchuangji@gmail.com\" is a valid ip address should be true")
- }
-}
-
-func TestBase64(t *testing.T) {
- valid := Validation{}
-
- if valid.Base64("suchuangji@gmail.com", "base64").Ok {
- t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false")
- }
- if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok {
- t.Error("\"c3VjaHVhbmdqaUBnbWFpbC5jb20=\" are a valid base64 characters should be true")
- }
-}
-
-func TestMobile(t *testing.T) {
- valid := Validation{}
-
- validMobiles := []string{
- "19800008888",
- "18800008888",
- "18000008888",
- "8618300008888",
- "+8614700008888",
- "17300008888",
- "+8617100008888",
- "8617500008888",
- "8617400008888",
- "16200008888",
- "16500008888",
- "16600008888",
- "16700008888",
- "13300008888",
- "14900008888",
- "15300008888",
- "17300008888",
- "17700008888",
- "18000008888",
- "18900008888",
- "19100008888",
- "19900008888",
- "19300008888",
- "13000008888",
- "13100008888",
- "13200008888",
- "14500008888",
- "15500008888",
- "15600008888",
- "16600008888",
- "17100008888",
- "17500008888",
- "17600008888",
- "18500008888",
- "18600008888",
- "13400008888",
- "13500008888",
- "13600008888",
- "13700008888",
- "13800008888",
- "13900008888",
- "14700008888",
- "15000008888",
- "15100008888",
- "15200008888",
- "15800008888",
- "15900008888",
- "17200008888",
- "17800008888",
- "18200008888",
- "18300008888",
- "18400008888",
- "18700008888",
- "18800008888",
- "19800008888",
- }
-
- for _, m := range validMobiles {
- if !valid.Mobile(m, "mobile").Ok {
- t.Error(m + " is a valid mobile phone number should be true")
- }
- }
-}
-
-func TestTel(t *testing.T) {
- valid := Validation{}
-
- if valid.Tel("222-00008888", "telephone").Ok {
- t.Error("\"222-00008888\" is a valid telephone number should be false")
- }
- if !valid.Tel("022-70008888", "telephone").Ok {
- t.Error("\"022-70008888\" is a valid telephone number should be true")
- }
- if !valid.Tel("02270008888", "telephone").Ok {
- t.Error("\"02270008888\" is a valid telephone number should be true")
- }
- if !valid.Tel("70008888", "telephone").Ok {
- t.Error("\"70008888\" is a valid telephone number should be true")
- }
-}
-
-func TestPhone(t *testing.T) {
- valid := Validation{}
-
- if valid.Phone("222-00008888", "phone").Ok {
- t.Error("\"222-00008888\" is a valid phone number should be false")
- }
- if !valid.Mobile("+8614700008888", "phone").Ok {
- t.Error("\"+8614700008888\" is a valid phone number should be true")
- }
- if !valid.Tel("02270008888", "phone").Ok {
- t.Error("\"02270008888\" is a valid phone number should be true")
- }
-}
-
-func TestZipCode(t *testing.T) {
- valid := Validation{}
-
- if valid.ZipCode("", "zipcode").Ok {
- t.Error("\"00008888\" is a valid zipcode should be false")
- }
- if !valid.ZipCode("536000", "zipcode").Ok {
- t.Error("\"536000\" is a valid zipcode should be true")
- }
-}
-
-func TestValid(t *testing.T) {
- type user struct {
- ID int
- Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
- Age int `valid:"Required;Range(1, 140)"`
- }
- valid := Validation{}
-
- u := user{Name: "test@/test/;com", Age: 40}
- b, err := valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if !b {
- t.Error("validation should be passed")
- }
-
- uptr := &user{Name: "test", Age: 40}
- valid.Clear()
- b, err = valid.Valid(uptr)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Error("validation should not be passed")
- }
- if len(valid.Errors) != 1 {
- t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors))
- }
- if valid.Errors[0].Key != "Name.Match" {
- t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key)
- }
-
- u = user{Name: "test@/test/;com", Age: 180}
- valid.Clear()
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Error("validation should not be passed")
- }
- if len(valid.Errors) != 1 {
- t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors))
- }
- if valid.Errors[0].Key != "Age.Range." {
- t.Errorf("Message key should be `Age.Range` but got %s", valid.Errors[0].Key)
- }
-}
-
-func TestRecursiveValid(t *testing.T) {
- type User struct {
- ID int
- Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
- Age int `valid:"Required;Range(1, 140)"`
- }
-
- type AnonymouseUser struct {
- ID2 int
- Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
- Age2 int `valid:"Required;Range(1, 140)"`
- }
-
- type Account struct {
- Password string `valid:"Required"`
- U User
- AnonymouseUser
- }
- valid := Validation{}
-
- u := Account{Password: "abc123_", U: User{}}
- b, err := valid.RecursiveValid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Error("validation should not be passed")
- }
-}
-
-func TestSkipValid(t *testing.T) {
- type User struct {
- ID int
-
- Email string `valid:"Email"`
- ReqEmail string `valid:"Required;Email"`
-
- IP string `valid:"IP"`
- ReqIP string `valid:"Required;IP"`
-
- Mobile string `valid:"Mobile"`
- ReqMobile string `valid:"Required;Mobile"`
-
- Tel string `valid:"Tel"`
- ReqTel string `valid:"Required;Tel"`
-
- Phone string `valid:"Phone"`
- ReqPhone string `valid:"Required;Phone"`
-
- ZipCode string `valid:"ZipCode"`
- ReqZipCode string `valid:"Required;ZipCode"`
- }
-
- u := User{
- ReqEmail: "a@a.com",
- ReqIP: "127.0.0.1",
- ReqMobile: "18888888888",
- ReqTel: "02088888888",
- ReqPhone: "02088888888",
- ReqZipCode: "510000",
- }
-
- valid := Validation{}
- b, err := valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should not be passed")
- }
-
- valid = Validation{RequiredFirst: true}
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if !b {
- t.Fatal("validation should be passed")
- }
-}
-
-func TestPointer(t *testing.T) {
- type User struct {
- ID int
-
- Email *string `valid:"Email"`
- ReqEmail *string `valid:"Required;Email"`
- }
-
- u := User{
- ReqEmail: nil,
- Email: nil,
- }
-
- valid := Validation{}
- b, err := valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should not be passed")
- }
-
- validEmail := "a@a.com"
- u = User{
- ReqEmail: &validEmail,
- Email: nil,
- }
-
- valid = Validation{RequiredFirst: true}
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if !b {
- t.Fatal("validation should be passed")
- }
-
- u = User{
- ReqEmail: &validEmail,
- Email: nil,
- }
-
- valid = Validation{}
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should not be passed")
- }
-
- invalidEmail := "a@a"
- u = User{
- ReqEmail: &validEmail,
- Email: &invalidEmail,
- }
-
- valid = Validation{RequiredFirst: true}
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should not be passed")
- }
-
- u = User{
- ReqEmail: &validEmail,
- Email: &invalidEmail,
- }
-
- valid = Validation{}
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should not be passed")
- }
-}
-
-func TestCanSkipAlso(t *testing.T) {
- type User struct {
- ID int
-
- Email string `valid:"Email"`
- ReqEmail string `valid:"Required;Email"`
- MatchRange int `valid:"Range(10, 20)"`
- }
-
- u := User{
- ReqEmail: "a@a.com",
- Email: "",
- MatchRange: 0,
- }
-
- valid := Validation{RequiredFirst: true}
- b, err := valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should not be passed")
- }
-
- valid = Validation{RequiredFirst: true}
- valid.CanSkipAlso("Range")
- b, err = valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if !b {
- t.Fatal("validation should be passed")
- }
-
-}
-
-func TestFieldNoEmpty(t *testing.T) {
- type User struct {
- Name string `json:"name" valid:"Match(/^[a-zA-Z][a-zA-Z0-9._-]{0,31}$/)"`
- }
- u := User{
- Name: "*",
- }
-
- valid := Validation{}
- b, err := valid.Valid(u)
- if err != nil {
- t.Fatal(err)
- }
- if b {
- t.Fatal("validation should be passed")
- }
- if len(valid.Errors) == 0 {
- t.Fatal("validation should be passed")
- }
- validErr := valid.Errors[0]
- if len(validErr.Field) == 0 {
- t.Fatal("validation should be passed")
- }
-}
diff --git a/doc.go b/doc.go
index 6975885a..8825bd29 100644
--- a/doc.go
+++ b/doc.go
@@ -1,15 +1,17 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+Package beego provide a MVC framework
+beego: an open-source, high-performance, modular, full-stack web framework
+It is used for rapid development of RESTful APIs, web apps and backend services in Go.
+beego is inspired by Tornado, Sinatra and Flask with the added benefit of some Go-specific features such as interfaces and struct embedding.
+
+ package main
+ import "github.com/astaxie/beego"
+
+ func main() {
+ beego.Run()
+ }
+
+more information: http://beego.me
+*/
package beego
diff --git a/server/web/error.go b/error.go
similarity index 94%
rename from server/web/error.go
rename to error.go
index b5ef1d2d..e5e9fd47 100644
--- a/server/web/error.go
+++ b/error.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"fmt"
@@ -23,14 +23,12 @@ import (
"strconv"
"strings"
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/core/utils"
-
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego/context"
+ "github.com/astaxie/beego/utils"
)
const (
- errorTypeHandler = iota
+ errorTypeHandler = iota
errorTypeController
)
@@ -92,7 +90,7 @@ func showErr(err interface{}, ctx *context.Context, stack string) {
"RequestURL": ctx.Input.URI(),
"RemoteAddr": ctx.Input.IP(),
"Stack": stack,
- "BeegoVersion": beego.VERSION,
+ "BeegoVersion": VERSION,
"GoVersion": runtime.Version(),
}
t.Execute(ctx.ResponseWriter, data)
@@ -361,25 +359,11 @@ func gatewayTimeout(rw http.ResponseWriter, r *http.Request) {
)
}
-// show 413 Payload Too Large
-func payloadTooLarge(rw http.ResponseWriter, r *http.Request) {
- responseError(rw, r,
- 413,
- ` The page you have requested is unavailable.
- Perhaps you are here because:
-
- The request entity is larger than limits defined by server.
- Please change the request entity and try again.
-
- `,
- )
-}
-
func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errContent string) {
t, _ := template.New("beegoerrortemp").Parse(errtpl)
data := M{
"Title": http.StatusText(errCode),
- "BeegoVersion": beego.VERSION,
+ "BeegoVersion": VERSION,
"Content": template.HTML(errContent),
}
t.Execute(rw, data)
@@ -389,7 +373,7 @@ func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errCont
// usage:
// beego.ErrorHandler("404",NotFound)
// beego.ErrorHandler("500",InternalServerError)
-func ErrorHandler(code string, h http.HandlerFunc) *HttpServer {
+func ErrorHandler(code string, h http.HandlerFunc) *App {
ErrorMaps[code] = &errorInfo{
errorType: errorTypeHandler,
handler: h,
@@ -401,7 +385,7 @@ func ErrorHandler(code string, h http.HandlerFunc) *HttpServer {
// ErrorController registers ControllerInterface to each http err code string.
// usage:
// beego.ErrorController(&controllers.ErrorController{})
-func ErrorController(c ControllerInterface) *HttpServer {
+func ErrorController(c ControllerInterface) *App {
reflectVal := reflect.ValueOf(c)
rt := reflectVal.Type()
ct := reflect.Indirect(reflectVal).Type()
diff --git a/server/web/error_test.go b/error_test.go
similarity index 99%
rename from server/web/error_test.go
rename to error_test.go
index 2685a985..378aa953 100644
--- a/server/web/error_test.go
+++ b/error_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"net/http"
diff --git a/adapter/filter.go b/filter.go
similarity index 79%
rename from adapter/filter.go
rename to filter.go
index 283d8879..9cc6e913 100644
--- a/adapter/filter.go
+++ b/filter.go
@@ -12,13 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package adapter
+package beego
-import (
- "github.com/astaxie/beego/adapter/context"
- "github.com/astaxie/beego/server/web"
- beecontext "github.com/astaxie/beego/server/web/context"
-)
+import "github.com/astaxie/beego/context"
// FilterFunc defines a filter function which is invoked before the controller handler is executed.
type FilterFunc func(*context.Context)
@@ -26,11 +22,23 @@ type FilterFunc func(*context.Context)
// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
// It can match the URL against a pattern, and execute a filter function
// when a request with a matching URL arrives.
-type FilterRouter web.FilterRouter
+type FilterRouter struct {
+ filterFunc FilterFunc
+ tree *Tree
+ pattern string
+ returnOnOutput bool
+ resetParams bool
+}
// ValidRouter checks if the current request is matched by this filter.
// If the request is matched, the values of the URL parameters defined
// by the filter pattern are also returned.
func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
- return (*web.FilterRouter)(f).ValidRouter(url, (*beecontext.Context)(ctx))
+ isOk := f.tree.Match(url, ctx)
+ if isOk != nil {
+ if b, ok := isOk.(bool); ok {
+ return b
+ }
+ }
+ return false
}
diff --git a/server/web/filter_test.go b/filter_test.go
similarity index 97%
rename from server/web/filter_test.go
rename to filter_test.go
index 11f575d6..4ca4d2b8 100644
--- a/server/web/filter_test.go
+++ b/filter_test.go
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"net/http"
"net/http/httptest"
"testing"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego/context"
)
var FilterUser = func(ctx *context.Context) {
diff --git a/server/web/flash.go b/flash.go
similarity index 99%
rename from server/web/flash.go
rename to flash.go
index 55f6435d..a6485a17 100644
--- a/server/web/flash.go
+++ b/flash.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"fmt"
diff --git a/server/web/flash_test.go b/flash_test.go
similarity index 99%
rename from server/web/flash_test.go
rename to flash_test.go
index 2deef54e..d5e9608d 100644
--- a/server/web/flash_test.go
+++ b/flash_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"net/http"
diff --git a/server/web/fs.go b/fs.go
similarity index 99%
rename from server/web/fs.go
rename to fs.go
index 5457457a..41cc6f6e 100644
--- a/server/web/fs.go
+++ b/fs.go
@@ -1,4 +1,4 @@
-package web
+package beego
import (
"net/http"
diff --git a/go.mod b/go.mod
index 7527aa47..ec500f51 100644
--- a/go.mod
+++ b/go.mod
@@ -7,53 +7,34 @@ require (
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
github.com/casbin/casbin v1.7.0
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58
- github.com/coreos/etcd v3.3.25+incompatible
- github.com/coreos/go-semver v0.3.0 // indirect
- github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
- github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808 // indirect
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a // indirect
github.com/elastic/go-elasticsearch/v6 v6.8.5
github.com/elazarl/go-bindata-assetfs v1.0.0
- github.com/go-kit/kit v0.9.0
github.com/go-redis/redis v6.14.2+incompatible
- github.com/go-redis/redis/v7 v7.4.0
github.com/go-sql-driver/mysql v1.5.0
- github.com/gogo/protobuf v1.3.1
+ github.com/gogo/protobuf v1.1.1
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
github.com/gomodule/redigo v2.0.0+incompatible
- github.com/google/go-cmp v0.5.0 // indirect
- github.com/google/uuid v1.1.1 // indirect
- github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/golang-lru v0.5.4
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6
github.com/lib/pq v1.0.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
- github.com/mitchellh/mapstructure v1.3.3
- github.com/opentracing/opentracing-go v1.2.0
- github.com/pelletier/go-toml v1.8.1
- github.com/pkg/errors v0.9.1
+ github.com/pelletier/go-toml v1.2.0 // indirect
github.com/prometheus/client_golang v1.7.0
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec
github.com/stretchr/testify v1.4.0
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
- go.etcd.io/etcd v3.3.25+incompatible // indirect
- go.uber.org/zap v1.15.0 // indirect
- golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
- golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
- golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 // indirect
- golang.org/x/text v0.3.3 // indirect
+ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c
- google.golang.org/grpc v1.26.0
gopkg.in/yaml.v2 v2.2.8
- honnef.co/go/tools v0.0.1-2020.1.5 // indirect
)
replace golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 => github.com/golang/crypto v0.0.0-20181127143415-eb0de9b17e85
replace gopkg.in/yaml.v2 v2.2.1 => github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d
-go 1.14
+go 1.13
diff --git a/go.sum b/go.sum
index 994d1ec4..c7b861ac 100644
--- a/go.sum
+++ b/go.sum
@@ -1,4 +1,3 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
@@ -21,22 +20,10 @@ github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 h1:rRISKWyXfVx
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/coreos/etcd v0.5.0-alpha.5 h1:0Qi6Jzjk2CDuuGlIeecpu+em2nrjhOgz2wsIwCmQHmc=
-github.com/coreos/etcd v3.3.25+incompatible h1:0GQEw6h3YnuOVdtwygkIfJ+Omx0tZ8/QkVyXI4LkbeY=
-github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
-github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
-github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
-github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d h1:OMrhQqj1QCyDT2sxHCDjE+k8aMdn2ngTCGG7g4wrdLo=
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808 h1:8s2l8TVUwMXl6tZMe3+hPCRJ25nQXiA3d1x622JtOqc=
@@ -54,45 +41,30 @@ github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiNaInPgym8nzfg0=
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
-github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d h1:xy93KVe+KrIIwWDEAfQBdIfsiHJkepbYsDr+VY3g9/o=
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
-github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -100,18 +72,11 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pO
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
@@ -119,10 +84,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -136,8 +98,6 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJK
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
-github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@@ -146,26 +106,19 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
-github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
-github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
-github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
+github.com/pingcap/tidb v2.0.11+incompatible/go.mod h1:I8C6jrPINP2rrVunTRd7C9fRRhQrtR43S1/CL5ix/yQ=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -174,7 +127,6 @@ github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -184,7 +136,6 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0 h1:QIF48X1cihydXibm+4wfAc0r/qyPyuFiPFRNphdMpEE=
@@ -208,137 +159,52 @@ github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2K
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b h1:0Ve0/CCjiAiyKddUMUn3RwIGlq2iTW4GuVzyoKBYO/8=
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
-go.etcd.io/etcd v0.5.0-alpha.5 h1:VOolFSo3XgsmnYDLozjvZ6JL6AAwIDu1Yx1y+4EYLDo=
-go.etcd.io/etcd v3.3.25+incompatible h1:V1RzkZJj9LqsJRy+TUBgpWSbZXITLB819lstuTFoZOY=
-go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
-go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
-go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
-go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 h1:AvbQYmiaaaza3cW3QXRyPo5kYgpFIzOAfeAAN7m3qQ4=
-golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200117065230-39095c1d176c h1:FodBYPZKH5tAN2O60HlglMwXGAeV/4k+NKbli79M/2c=
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200815165600-90abf76919f3 h1:0aScV/0rLmANzEYIhjCOi2pTvDyhZNduBUMD2q3iqs4=
-golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
-google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
-google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
@@ -349,9 +215,3 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75k=
-honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
diff --git a/server/web/grace/grace.go b/grace/grace.go
similarity index 100%
rename from server/web/grace/grace.go
rename to grace/grace.go
diff --git a/server/web/grace/server.go b/grace/server.go
similarity index 98%
rename from server/web/grace/server.go
rename to grace/server.go
index 13fa6e34..008a6171 100644
--- a/server/web/grace/server.go
+++ b/grace/server.go
@@ -29,8 +29,8 @@ type Server struct {
terminalChan chan error
}
-// Serve accepts incoming connections on the Listener l
-// and creates a new service goroutine for each.
+// Serve accepts incoming connections on the Listener l,
+// creating a new service goroutine for each.
// The service goroutines read requests and then call srv.Handler to reply to them.
func (srv *Server) Serve() (err error) {
srv.state = StateRunning
diff --git a/server/web/hooks.go b/hooks.go
similarity index 84%
rename from server/web/hooks.go
rename to hooks.go
index 58e2c0f3..b8671d35 100644
--- a/server/web/hooks.go
+++ b/hooks.go
@@ -1,4 +1,4 @@
-package web
+package beego
import (
"encoding/json"
@@ -6,9 +6,9 @@ import (
"net/http"
"path/filepath"
- "github.com/astaxie/beego/core/logs"
- "github.com/astaxie/beego/server/web/context"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/astaxie/beego/context"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/session"
)
// register MIME type with content type
@@ -34,7 +34,6 @@ func registerDefaultErrorHandler() error {
"504": gatewayTimeout,
"417": invalidxsrf,
"422": missingxsrf,
- "413": payloadTooLarge,
}
for e, h := range m {
if _, ok := ErrorMaps[e]; !ok {
@@ -47,9 +46,9 @@ func registerDefaultErrorHandler() error {
func registerSession() error {
if BConfig.WebConfig.Session.SessionOn {
var err error
- sessionConfig, err := AppConfig.String("sessionConfig")
+ sessionConfig := AppConfig.String("sessionConfig")
conf := new(session.ManagerConfig)
- if sessionConfig == "" || err != nil {
+ if sessionConfig == "" {
conf.CookieName = BConfig.WebConfig.Session.SessionName
conf.EnableSetCookie = BConfig.WebConfig.Session.SessionAutoSetCookie
conf.Gclifetime = BConfig.WebConfig.Session.SessionGCMaxLifetime
@@ -85,6 +84,13 @@ func registerTemplate() error {
return nil
}
+func registerAdmin() error {
+ if BConfig.Listen.EnableAdmin {
+ go beeAdminApp.Run()
+ }
+ return nil
+}
+
func registerGzip() error {
if BConfig.EnableGzip {
context.InitGzip(
@@ -95,13 +101,3 @@ func registerGzip() error {
}
return nil
}
-
-func registerCommentRouter() error {
- if BConfig.RunMode == DEV {
- if err := parserPkg(filepath.Join(WorkPath, BConfig.WebConfig.CommentRouterPath)); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/client/httplib/README.md b/httplib/README.md
similarity index 100%
rename from client/httplib/README.md
rename to httplib/README.md
diff --git a/client/httplib/httplib.go b/httplib/httplib.go
similarity index 85%
rename from client/httplib/httplib.go
rename to httplib/httplib.go
index f8ab80a1..e094a6a6 100644
--- a/client/httplib/httplib.go
+++ b/httplib/httplib.go
@@ -34,7 +34,6 @@ package httplib
import (
"bytes"
"compress/gzip"
- "context"
"crypto/tls"
"encoding/json"
"encoding/xml"
@@ -67,11 +66,6 @@ var defaultSetting = BeegoHTTPSettings{
var defaultCookieJar http.CookieJar
var settingMutex sync.Mutex
-// it will be the last filter and execute request.Do
-var doRequestFilter = func(ctx context.Context, req *BeegoHTTPRequest) (*http.Response, error) {
- return req.doRequest(ctx)
-}
-
// createDefaultCookie creates a global cookiejar to store cookies.
func createDefaultCookie() {
settingMutex.Lock()
@@ -79,14 +73,14 @@ func createDefaultCookie() {
defaultCookieJar, _ = cookiejar.New(nil)
}
-// SetDefaultSetting overwrites default settings
+// SetDefaultSetting Overwrite default settings
func SetDefaultSetting(setting BeegoHTTPSettings) {
settingMutex.Lock()
defer settingMutex.Unlock()
defaultSetting = setting
}
-// NewBeegoRequest returns *BeegoHttpRequest with specific method
+// NewBeegoRequest return *BeegoHttpRequest with specific method
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
var resp http.Response
u, err := url.Parse(rawurl)
@@ -150,11 +144,9 @@ type BeegoHTTPSettings struct {
Gzip bool
DumpBody bool
Retries int // if set to -1 means will retry forever
- RetryDelay time.Duration
- FilterChains []FilterChain
}
-// BeegoHTTPRequest provides more useful methods than http.Request for requesting a url.
+// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
type BeegoHTTPRequest struct {
url string
req *http.Request
@@ -166,12 +158,12 @@ type BeegoHTTPRequest struct {
dump []byte
}
-// GetRequest returns the request object
+// GetRequest return the request object
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
return b.req
}
-// Setting changes request settings
+// Setting Change request settings
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
b.setting = setting
return b
@@ -202,27 +194,21 @@ func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
}
// Retries sets Retries times.
-// default is 0 (never retry)
-// -1 retry indefinitely (forever)
-// Other numbers specify the exact retry amount
+// default is 0 means no retried.
+// -1 means retried forever.
+// others means retried times.
func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
b.setting.Retries = times
return b
}
-// RetryDelay sets the time to sleep between reconnection attempts
-func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
- b.setting.RetryDelay = delay
- return b
-}
-
-// DumpBody sets the DumbBody field
+// DumpBody setting whether need to Dump the Body.
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
b.setting.DumpBody = isdump
return b
}
-// DumpRequest returns the DumpRequest
+// DumpRequest return the DumpRequest
func (b *BeegoHTTPRequest) DumpRequest() []byte {
return b.dump
}
@@ -234,13 +220,13 @@ func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Dura
return b
}
-// SetTLSClientConfig sets TLS connection configuration if visiting HTTPS url.
+// SetTLSClientConfig sets tls connection configurations if visiting https url.
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
b.setting.TLSClientConfig = config
return b
}
-// Header adds header item string in request.
+// Header add header item string in request.
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
b.req.Header.Set(key, value)
return b
@@ -252,7 +238,7 @@ func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
return b
}
-// SetProtocolVersion sets the protocol version for incoming requests.
+// SetProtocolVersion Set the protocol version for incoming requests.
// Client requests always use HTTP/1.1.
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
if len(vers) == 0 {
@@ -269,19 +255,19 @@ func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
return b
}
-// SetCookie adds a cookie to the request.
+// SetCookie add cookie into request.
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
b.req.Header.Add("Cookie", cookie.String())
return b
}
-// SetTransport sets the transport field
+// SetTransport set the setting transport
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
b.setting.Transport = transport
return b
}
-// SetProxy sets the HTTP proxy
+// SetProxy set the http proxy
// example:
//
// func(req *http.Request) (*url.URL, error) {
@@ -302,18 +288,6 @@ func (b *BeegoHTTPRequest) SetCheckRedirect(redirect func(req *http.Request, via
return b
}
-// SetFilters will use the filter as the invocation filters
-func (b *BeegoHTTPRequest) SetFilters(fcs ...FilterChain) *BeegoHTTPRequest {
- b.setting.FilterChains = fcs
- return b
-}
-
-// AddFilters adds filter
-func (b *BeegoHTTPRequest) AddFilters(fcs ...FilterChain) *BeegoHTTPRequest {
- b.setting.FilterChains = append(b.setting.FilterChains, fcs...)
- return b
-}
-
// Param adds query param in to request.
// params build query string as ?key1=value1&key2=value2...
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
@@ -325,14 +299,14 @@ func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
return b
}
-// PostFile adds a post file to the request
+// PostFile add a post file to the request
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
b.files[formname] = filename
return b
}
// Body adds request raw body.
-// Supports string and []byte.
+// it supports string and []byte.
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
switch t := data.(type) {
case string:
@@ -347,7 +321,7 @@ func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
return b
}
-// XMLBody adds the request raw body encoded in XML.
+// XMLBody adds request raw body encoding by XML.
func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
if b.req.Body == nil && obj != nil {
byts, err := xml.Marshal(obj)
@@ -361,7 +335,7 @@ func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
return b, nil
}
-// YAMLBody adds the request raw body encoded in YAML.
+// YAMLBody adds request raw body encoding by YAML.
func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
if b.req.Body == nil && obj != nil {
byts, err := yaml.Marshal(obj)
@@ -375,7 +349,7 @@ func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error)
return b, nil
}
-// JSONBody adds the request raw body encoded in JSON.
+// JSONBody adds request raw body encoding by JSON.
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
if b.req.Body == nil && obj != nil {
byts, err := json.Marshal(obj)
@@ -416,7 +390,7 @@ func (b *BeegoHTTPRequest) buildURL(paramBody string) {
if err != nil {
log.Println("Httplib:", err)
}
- // iocopy
+ //iocopy
_, err = io.Copy(fileWriter, fh)
fh.Close()
if err != nil {
@@ -457,23 +431,8 @@ func (b *BeegoHTTPRequest) getResponse() (*http.Response, error) {
return resp, nil
}
-// DoRequest executes client.Do
+// DoRequest will do the client.Do
func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
- return b.DoRequestWithCtx(context.Background())
-}
-
-func (b *BeegoHTTPRequest) DoRequestWithCtx(ctx context.Context) (resp *http.Response, err error) {
-
- root := doRequestFilter
- if len(b.setting.FilterChains) > 0 {
- for i := len(b.setting.FilterChains) - 1; i >= 0; i-- {
- root = b.setting.FilterChains[i](root)
- }
- }
- return root(ctx, b)
-}
-
-func (b *BeegoHTTPRequest) doRequest(ctx context.Context) (resp *http.Response, err error) {
var paramBody string
if len(b.params) > 0 {
var buf bytes.Buffer
@@ -553,19 +512,17 @@ func (b *BeegoHTTPRequest) doRequest(ctx context.Context) (resp *http.Response,
// retries default value is 0, it will run once.
// retries equal to -1, it will run forever until success
// retries is setted, it will retries fixed times.
- // Sleeps for a 400ms inbetween calls to reduce spam
for i := 0; b.setting.Retries == -1 || i <= b.setting.Retries; i++ {
resp, err = client.Do(b.req)
if err == nil {
break
}
- time.Sleep(b.setting.RetryDelay)
}
return resp, err
}
// String returns the body string in response.
-// Calls Response inner.
+// it calls Response inner.
func (b *BeegoHTTPRequest) String() (string, error) {
data, err := b.Bytes()
if err != nil {
@@ -576,7 +533,7 @@ func (b *BeegoHTTPRequest) String() (string, error) {
}
// Bytes returns the body []byte in response.
-// Calls Response inner.
+// it calls Response inner.
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
if b.body != nil {
return b.body, nil
@@ -602,7 +559,7 @@ func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
}
// ToFile saves the body data in response to one file.
-// Calls Response inner.
+// it calls Response inner.
func (b *BeegoHTTPRequest) ToFile(filename string) error {
resp, err := b.getResponse()
if err != nil {
@@ -625,7 +582,7 @@ func (b *BeegoHTTPRequest) ToFile(filename string) error {
return err
}
-// Check if the file directory exists. If it doesn't then it's created
+//Check that the file directory exists, there is no automatically created
func pathExistAndMkdir(filename string) (err error) {
filename = path.Dir(filename)
_, err = os.Stat(filename)
@@ -641,8 +598,8 @@ func pathExistAndMkdir(filename string) (err error) {
return err
}
-// ToJSON returns the map that marshals from the body bytes as json in response.
-// Calls Response inner.
+// ToJSON returns the map that marshals from the body bytes as json in response .
+// it calls Response inner.
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
data, err := b.Bytes()
if err != nil {
@@ -652,7 +609,7 @@ func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
}
// ToXML returns the map that marshals from the body bytes as xml in response .
-// Calls Response inner.
+// it calls Response inner.
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
data, err := b.Bytes()
if err != nil {
@@ -662,7 +619,7 @@ func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
}
// ToYAML returns the map that marshals from the body bytes as yaml in response .
-// Calls Response inner.
+// it calls Response inner.
func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
data, err := b.Bytes()
if err != nil {
@@ -671,7 +628,7 @@ func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
return yaml.Unmarshal(data, v)
}
-// Response executes request client gets response manually.
+// Response executes request client gets response mannually.
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
return b.getResponse()
}
diff --git a/adapter/httplib/httplib_test.go b/httplib/httplib_test.go
similarity index 86%
rename from adapter/httplib/httplib_test.go
rename to httplib/httplib_test.go
index e7605c87..dd2a4f1c 100644
--- a/adapter/httplib/httplib_test.go
+++ b/httplib/httplib_test.go
@@ -15,7 +15,6 @@
package httplib
import (
- "errors"
"io/ioutil"
"net"
"net/http"
@@ -34,34 +33,6 @@ func TestResponse(t *testing.T) {
t.Log(resp)
}
-func TestDoRequest(t *testing.T) {
- req := Get("https://goolnk.com/33BD2j")
- retryAmount := 1
- req.Retries(1)
- req.RetryDelay(1400 * time.Millisecond)
- retryDelay := 1400 * time.Millisecond
-
- req.SetCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error {
- return errors.New("Redirect triggered")
- })
-
- startTime := time.Now().UnixNano() / int64(time.Millisecond)
-
- _, err := req.Response()
- if err == nil {
- t.Fatal("Response should have yielded an error")
- }
-
- endTime := time.Now().UnixNano() / int64(time.Millisecond)
- elapsedTime := endTime - startTime
- delayedTime := int64(retryAmount) * retryDelay.Milliseconds()
-
- if elapsedTime < delayedTime {
- t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime)
- }
-
-}
-
func TestGet(t *testing.T) {
req := Get("http://httpbin.org/get")
b, err := req.Bytes()
@@ -98,7 +69,7 @@ func TestSimplePost(t *testing.T) {
}
}
-// func TestPostFile(t *testing.T) {
+//func TestPostFile(t *testing.T) {
// v := "smallfish"
// req := Post("http://httpbin.org/post")
// req.Debug(true)
@@ -115,7 +86,7 @@ func TestSimplePost(t *testing.T) {
// if n == -1 {
// t.Fatal(v + " not found in post")
// }
-// }
+//}
func TestSimplePut(t *testing.T) {
str, err := Put("http://httpbin.org/put").String()
diff --git a/adapter/log.go b/log.go
similarity index 88%
rename from adapter/log.go
rename to log.go
index 9d07ec1a..cc4c0f81 100644
--- a/adapter/log.go
+++ b/log.go
@@ -12,27 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package adapter
+package beego
import (
"strings"
- "github.com/astaxie/beego/core/logs"
-
- webLog "github.com/astaxie/beego/core/logs"
+ "github.com/astaxie/beego/logs"
)
// Log levels to control the logging output.
// Deprecated: use github.com/astaxie/beego/logs instead.
const (
- LevelEmergency = webLog.LevelEmergency
- LevelAlert = webLog.LevelAlert
- LevelCritical = webLog.LevelCritical
- LevelError = webLog.LevelError
- LevelWarning = webLog.LevelWarning
- LevelNotice = webLog.LevelNotice
- LevelInformational = webLog.LevelInformational
- LevelDebug = webLog.LevelDebug
+ LevelEmergency = iota
+ LevelAlert
+ LevelCritical
+ LevelError
+ LevelWarning
+ LevelNotice
+ LevelInformational
+ LevelDebug
)
// BeeLogger references the used application logger.
diff --git a/core/logs/README.md b/logs/README.md
similarity index 100%
rename from core/logs/README.md
rename to logs/README.md
diff --git a/core/logs/access_log.go b/logs/accesslog.go
similarity index 89%
rename from core/logs/access_log.go
rename to logs/accesslog.go
index 10455fe9..3ff9e20f 100644
--- a/core/logs/access_log.go
+++ b/logs/accesslog.go
@@ -16,9 +16,9 @@ package logs
import (
"bytes"
+ "strings"
"encoding/json"
"fmt"
- "strings"
"time"
)
@@ -28,7 +28,7 @@ const (
jsonFormat = "JSON_FORMAT"
)
-// AccessLogRecord is astruct for holding access log data.
+// AccessLogRecord struct for holding access log data.
type AccessLogRecord struct {
RemoteAddr string `json:"remote_addr"`
RequestTime time.Time `json:"request_time"`
@@ -63,17 +63,7 @@ func disableEscapeHTML(i interface{}) {
// AccessLog - Format and print access log.
func AccessLog(r *AccessLogRecord, format string) {
- msg := r.format(format)
- lm := &LogMsg{
- Msg: strings.TrimSpace(msg),
- When: time.Now(),
- Level: levelLoggerImpl,
- }
- beeLogger.writeMsg(lm)
-}
-
-func (r *AccessLogRecord) format(format string) string {
- msg := ""
+ var msg string
switch format {
case apacheFormat:
timeFormatted := r.RequestTime.Format("02/Jan/2006 03:04:05")
@@ -89,5 +79,5 @@ func (r *AccessLogRecord) format(format string) string {
msg = string(jsonData)
}
}
- return msg
+ beeLogger.writeMsg(levelLoggerImpl, strings.TrimSpace(msg))
}
diff --git a/core/logs/alils/alils.go b/logs/alils/alils.go
similarity index 69%
rename from core/logs/alils/alils.go
rename to logs/alils/alils.go
index 484d31e4..867ff4cb 100644
--- a/core/logs/alils/alils.go
+++ b/logs/alils/alils.go
@@ -2,20 +2,18 @@ package alils
import (
"encoding/json"
- "fmt"
"strings"
"sync"
+ "time"
+ "github.com/astaxie/beego/logs"
"github.com/gogo/protobuf/proto"
- "github.com/pkg/errors"
-
- "github.com/astaxie/beego/core/logs"
)
const (
- // CacheSize sets the flush size
+ // CacheSize set the flush size
CacheSize int = 64
- // Delimiter defines the topic delimiter
+ // Delimiter define the topic delimiter
Delimiter string = "##"
)
@@ -30,11 +28,10 @@ type Config struct {
Source string `json:"source"`
Level int `json:"level"`
FlushWhen int `json:"flush_when"`
- Formatter string `json:"formatter"`
}
// aliLSWriter implements LoggerInterface.
-// Writes messages in keep-live tcp connection.
+// it writes messages in keep-live tcp connection.
type aliLSWriter struct {
store *LogStore
group []*LogGroup
@@ -42,23 +39,19 @@ type aliLSWriter struct {
groupMap map[string]*LogGroup
lock *sync.Mutex
Config
- formatter logs.LogFormatter
}
-// NewAliLS creates a new Logger
+// NewAliLS create a new Logger
func NewAliLS() logs.Logger {
alils := new(aliLSWriter)
alils.Level = logs.LevelTrace
- alils.formatter = alils
return alils
}
-// Init parses config and initializes struct
-func (c *aliLSWriter) Init(config string) error {
- err := json.Unmarshal([]byte(config), c)
- if err != nil {
- return err
- }
+// Init parse config and init struct
+func (c *aliLSWriter) Init(jsonConfig string) (err error) {
+
+ json.Unmarshal([]byte(jsonConfig), c)
if c.FlushWhen > CacheSize {
c.FlushWhen = CacheSize
@@ -71,13 +64,11 @@ func (c *aliLSWriter) Init(config string) error {
AccessKeySecret: c.KeySecret,
}
- store, err := prj.GetLogStore(c.LogStore)
+ c.store, err = prj.GetLogStore(c.LogStore)
if err != nil {
return err
}
- c.store = store
-
// Create default Log Group
c.group = append(c.group, &LogGroup{
Topic: proto.String(""),
@@ -107,29 +98,14 @@ func (c *aliLSWriter) Init(config string) error {
c.lock = &sync.Mutex{}
- if len(c.Formatter) > 0 {
- fmtr, ok := logs.GetFormatter(c.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", c.Formatter))
- }
- c.formatter = fmtr
- }
-
return nil
}
-func (c *aliLSWriter) Format(lm *logs.LogMsg) string {
- return lm.OldStyleFormat()
-}
+// WriteMsg write message in connection.
+// if connection is down, try to re-connect.
+func (c *aliLSWriter) WriteMsg(when time.Time, msg string, level int) (err error) {
-func (c *aliLSWriter) SetFormatter(f logs.LogFormatter) {
- c.formatter = f
-}
-
-// WriteMsg writes a message in connection.
-// If connection is down, try to re-connect.
-func (c *aliLSWriter) WriteMsg(lm *logs.LogMsg) error {
- if lm.Level > c.Level {
+ if level > c.Level {
return nil
}
@@ -139,30 +115,31 @@ func (c *aliLSWriter) WriteMsg(lm *logs.LogMsg) error {
if c.withMap {
// Topic,LogGroup
- strs := strings.SplitN(lm.Msg, Delimiter, 2)
+ strs := strings.SplitN(msg, Delimiter, 2)
if len(strs) == 2 {
pos := strings.LastIndex(strs[0], " ")
topic = strs[0][pos+1 : len(strs[0])]
+ content = strs[0][0:pos] + strs[1]
lg = c.groupMap[topic]
}
// send to empty Topic
if lg == nil {
+ content = msg
lg = c.group[0]
}
} else {
+ content = msg
lg = c.group[0]
}
- content = c.formatter.Format(lm)
-
c1 := &LogContent{
Key: proto.String("msg"),
Value: proto.String(content),
}
l := &Log{
- Time: proto.Uint32(uint32(lm.When.Unix())),
+ Time: proto.Uint32(uint32(when.Unix())),
Contents: []*LogContent{
c1,
},
@@ -175,6 +152,7 @@ func (c *aliLSWriter) WriteMsg(lm *logs.LogMsg) error {
if len(lg.Logs) >= c.FlushWhen {
c.flush(lg)
}
+
return nil
}
diff --git a/core/logs/alils/config.go b/logs/alils/config.go
similarity index 61%
rename from core/logs/alils/config.go
rename to logs/alils/config.go
index d0b67c24..e8c24448 100755
--- a/core/logs/alils/config.go
+++ b/logs/alils/config.go
@@ -4,10 +4,10 @@ const (
version = "0.5.0" // SDK version
signatureMethod = "hmac-sha1" // Signature method
- // OffsetNewest is the log head offset, i.e. the offset that will be
+ // OffsetNewest stands for the log head offset, i.e. the offset that will be
// assigned to the next message that will be produced to the shard.
OffsetNewest = "end"
- // OffsetOldest is the the oldest offset available on the logstore for a
+ // OffsetOldest stands for the oldest offset available on the logstore for a
// shard.
OffsetOldest = "begin"
)
diff --git a/core/logs/alils/log.pb.go b/logs/alils/log.pb.go
similarity index 95%
rename from core/logs/alils/log.pb.go
rename to logs/alils/log.pb.go
index b18fb9b7..601b0d78 100755
--- a/core/logs/alils/log.pb.go
+++ b/logs/alils/log.pb.go
@@ -31,13 +31,13 @@ type Log struct {
// Reset the Log
func (m *Log) Reset() { *m = Log{} }
-// String returns the Compact Log
+// String return the Compact Log
func (m *Log) String() string { return proto.CompactTextString(m) }
// ProtoMessage not implemented
func (*Log) ProtoMessage() {}
-// GetTime returns the Log's Time
+// GetTime return the Log's Time
func (m *Log) GetTime() uint32 {
if m != nil && m.Time != nil {
return *m.Time
@@ -45,7 +45,7 @@ func (m *Log) GetTime() uint32 {
return 0
}
-// GetContents returns the Log's Contents
+// GetContents return the Log's Contents
func (m *Log) GetContents() []*LogContent {
if m != nil {
return m.Contents
@@ -53,7 +53,7 @@ func (m *Log) GetContents() []*LogContent {
return nil
}
-// LogContent defines the Log content struct
+// LogContent define the Log content struct
type LogContent struct {
Key *string `protobuf:"bytes,1,req,name=Key" json:"Key,omitempty"`
Value *string `protobuf:"bytes,2,req,name=Value" json:"Value,omitempty"`
@@ -63,13 +63,13 @@ type LogContent struct {
// Reset LogContent
func (m *LogContent) Reset() { *m = LogContent{} }
-// String returns the compact text
+// String return the compact text
func (m *LogContent) String() string { return proto.CompactTextString(m) }
// ProtoMessage not implemented
func (*LogContent) ProtoMessage() {}
-// GetKey returns the key
+// GetKey return the Key
func (m *LogContent) GetKey() string {
if m != nil && m.Key != nil {
return *m.Key
@@ -77,7 +77,7 @@ func (m *LogContent) GetKey() string {
return ""
}
-// GetValue returns the value
+// GetValue return the Value
func (m *LogContent) GetValue() string {
if m != nil && m.Value != nil {
return *m.Value
@@ -85,7 +85,7 @@ func (m *LogContent) GetValue() string {
return ""
}
-// LogGroup defines the logs struct
+// LogGroup define the logs struct
type LogGroup struct {
Logs []*Log `protobuf:"bytes,1,rep,name=Logs" json:"Logs,omitempty"`
Reserved *string `protobuf:"bytes,2,opt,name=Reserved" json:"Reserved,omitempty"`
@@ -97,13 +97,13 @@ type LogGroup struct {
// Reset LogGroup
func (m *LogGroup) Reset() { *m = LogGroup{} }
-// String returns the compact text
+// String return the compact text
func (m *LogGroup) String() string { return proto.CompactTextString(m) }
// ProtoMessage not implemented
func (*LogGroup) ProtoMessage() {}
-// GetLogs returns the loggroup logs
+// GetLogs return the loggroup logs
func (m *LogGroup) GetLogs() []*Log {
if m != nil {
return m.Logs
@@ -111,8 +111,7 @@ func (m *LogGroup) GetLogs() []*Log {
return nil
}
-// GetReserved returns Reserved. An empty string is returned
-// if an error occurs
+// GetReserved return Reserved
func (m *LogGroup) GetReserved() string {
if m != nil && m.Reserved != nil {
return *m.Reserved
@@ -120,8 +119,7 @@ func (m *LogGroup) GetReserved() string {
return ""
}
-// GetTopic returns Topic. An empty string is returned
-// if an error occurs
+// GetTopic return Topic
func (m *LogGroup) GetTopic() string {
if m != nil && m.Topic != nil {
return *m.Topic
@@ -129,8 +127,7 @@ func (m *LogGroup) GetTopic() string {
return ""
}
-// GetSource returns source. An empty string is returned
-// if an error occurs
+// GetSource return Source
func (m *LogGroup) GetSource() string {
if m != nil && m.Source != nil {
return *m.Source
@@ -138,7 +135,7 @@ func (m *LogGroup) GetSource() string {
return ""
}
-// LogGroupList defines the LogGroups
+// LogGroupList define the LogGroups
type LogGroupList struct {
LogGroups []*LogGroup `protobuf:"bytes,1,rep,name=logGroups" json:"logGroups,omitempty"`
XXXUnrecognized []byte `json:"-"`
@@ -147,13 +144,13 @@ type LogGroupList struct {
// Reset LogGroupList
func (m *LogGroupList) Reset() { *m = LogGroupList{} }
-// String returns compact text
+// String return compact text
func (m *LogGroupList) String() string { return proto.CompactTextString(m) }
// ProtoMessage not implemented
func (*LogGroupList) ProtoMessage() {}
-// GetLogGroups returns the LogGroups
+// GetLogGroups return the LogGroups
func (m *LogGroupList) GetLogGroups() []*LogGroup {
if m != nil {
return m.LogGroups
@@ -161,7 +158,7 @@ func (m *LogGroupList) GetLogGroups() []*LogGroup {
return nil
}
-// Marshal marshals the logs to byte slice
+// Marshal the logs to byte slice
func (m *Log) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
@@ -356,7 +353,7 @@ func encodeVarintLog(data []byte, offset int, v uint64) int {
return offset + 1
}
-// Size returns the log's size
+// Size return the log's size
func (m *Log) Size() (n int) {
var l int
_ = l
@@ -375,7 +372,7 @@ func (m *Log) Size() (n int) {
return n
}
-// Size returns LogContent size based on Key and Value
+// Size return LogContent size based on Key and Value
func (m *LogContent) Size() (n int) {
var l int
_ = l
@@ -393,7 +390,7 @@ func (m *LogContent) Size() (n int) {
return n
}
-// Size returns LogGroup size based on Logs
+// Size return LogGroup size based on Logs
func (m *LogGroup) Size() (n int) {
var l int
_ = l
@@ -421,7 +418,7 @@ func (m *LogGroup) Size() (n int) {
return n
}
-// Size returns LogGroupList size
+// Size return LogGroupList size
func (m *LogGroupList) Size() (n int) {
var l int
_ = l
@@ -451,7 +448,7 @@ func sozLog(x uint64) (n int) {
return sovLog((x << 1) ^ (x >> 63))
}
-// Unmarshal unmarshals data to log
+// Unmarshal data to log
func (m *Log) Unmarshal(data []byte) error {
var hasFields [1]uint64
l := len(data)
@@ -560,7 +557,7 @@ func (m *Log) Unmarshal(data []byte) error {
return nil
}
-// Unmarshal unmarshals data to LogContent
+// Unmarshal data to LogContent
func (m *LogContent) Unmarshal(data []byte) error {
var hasFields [1]uint64
l := len(data)
@@ -682,7 +679,7 @@ func (m *LogContent) Unmarshal(data []byte) error {
return nil
}
-// Unmarshal unmarshals data to LogGroup
+// Unmarshal data to LogGroup
func (m *LogGroup) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
@@ -856,7 +853,7 @@ func (m *LogGroup) Unmarshal(data []byte) error {
return nil
}
-// Unmarshal unmarshals data to LogGroupList
+// Unmarshal data to LogGroupList
func (m *LogGroupList) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
diff --git a/core/logs/alils/log_config.go b/logs/alils/log_config.go
similarity index 91%
rename from core/logs/alils/log_config.go
rename to logs/alils/log_config.go
index 7daeb864..e8564efb 100755
--- a/core/logs/alils/log_config.go
+++ b/logs/alils/log_config.go
@@ -1,6 +1,6 @@
package alils
-// InputDetail defines log detail
+// InputDetail define log detail
type InputDetail struct {
LogType string `json:"logType"`
LogPath string `json:"logPath"`
@@ -15,13 +15,13 @@ type InputDetail struct {
TopicFormat string `json:"topicFormat"`
}
-// OutputDetail defines the output detail
+// OutputDetail define the output detail
type OutputDetail struct {
Endpoint string `json:"endpoint"`
LogStoreName string `json:"logstoreName"`
}
-// LogConfig defines Log Config
+// LogConfig define Log Config
type LogConfig struct {
Name string `json:"configName"`
InputType string `json:"inputType"`
diff --git a/core/logs/alils/log_project.go b/logs/alils/log_project.go
similarity index 99%
rename from core/logs/alils/log_project.go
rename to logs/alils/log_project.go
index 7ede3fef..59db8cbf 100755
--- a/core/logs/alils/log_project.go
+++ b/logs/alils/log_project.go
@@ -20,7 +20,7 @@ type errorMessage struct {
Message string `json:"errorMessage"`
}
-// LogProject defines the Ali Project detail
+// LogProject Define the Ali Project detail
type LogProject struct {
Name string // Project name
Endpoint string // IP or hostname of SLS endpoint
diff --git a/core/logs/alils/log_store.go b/logs/alils/log_store.go
similarity index 98%
rename from core/logs/alils/log_store.go
rename to logs/alils/log_store.go
index d5ff25e2..fa502736 100755
--- a/core/logs/alils/log_store.go
+++ b/logs/alils/log_store.go
@@ -12,7 +12,7 @@ import (
"github.com/gogo/protobuf/proto"
)
-// LogStore stores the logs
+// LogStore Store the logs
type LogStore struct {
Name string `json:"logstoreName"`
TTL int
@@ -24,7 +24,7 @@ type LogStore struct {
project *LogProject
}
-// Shard defines the Log Shard
+// Shard define the Log Shard
type Shard struct {
ShardID int `json:"shardID"`
}
@@ -71,7 +71,7 @@ func (s *LogStore) ListShards() (shardIDs []int, err error) {
return
}
-// PutLogs puts logs into logstore.
+// PutLogs put logs into logstore.
// The callers should transform user logs into LogGroup.
func (s *LogStore) PutLogs(lg *LogGroup) (err error) {
body, err := proto.Marshal(lg)
diff --git a/core/logs/alils/machine_group.go b/logs/alils/machine_group.go
similarity index 88%
rename from core/logs/alils/machine_group.go
rename to logs/alils/machine_group.go
index 101faeb4..b6c69a14 100755
--- a/core/logs/alils/machine_group.go
+++ b/logs/alils/machine_group.go
@@ -8,13 +8,13 @@ import (
"net/http/httputil"
)
-// MachineGroupAttribute defines the Attribute
+// MachineGroupAttribute define the Attribute
type MachineGroupAttribute struct {
ExternalName string `json:"externalName"`
TopicName string `json:"groupTopic"`
}
-// MachineGroup defines the machine Group
+// MachineGroup define the machine Group
type MachineGroup struct {
Name string `json:"groupName"`
Type string `json:"groupType"`
@@ -29,20 +29,20 @@ type MachineGroup struct {
project *LogProject
}
-// Machine defines the Machine
+// Machine define the Machine
type Machine struct {
IP string
UniqueID string `json:"machine-uniqueid"`
UserdefinedID string `json:"userdefined-id"`
}
-// MachineList defines the Machine List
+// MachineList define the Machine List
type MachineList struct {
Total int
Machines []*Machine
}
-// ListMachines returns the machine list of this machine group.
+// ListMachines returns machine list of this machine group.
func (m *MachineGroup) ListMachines() (ms []*Machine, total int, err error) {
h := map[string]string{
"x-sls-bodyrawsize": "0",
diff --git a/core/logs/alils/request.go b/logs/alils/request.go
similarity index 100%
rename from core/logs/alils/request.go
rename to logs/alils/request.go
diff --git a/core/logs/alils/signature.go b/logs/alils/signature.go
similarity index 100%
rename from core/logs/alils/signature.go
rename to logs/alils/signature.go
diff --git a/core/logs/conn.go b/logs/conn.go
similarity index 65%
rename from core/logs/conn.go
rename to logs/conn.go
index 1fd71be7..afe0cbb7 100644
--- a/core/logs/conn.go
+++ b/logs/conn.go
@@ -16,20 +16,16 @@ package logs
import (
"encoding/json"
- "fmt"
"io"
"net"
-
- "github.com/pkg/errors"
+ "time"
)
// connWriter implements LoggerInterface.
-// Writes messages in keep-live tcp connection.
+// it writes messages in keep-live tcp connection.
type connWriter struct {
lg *logWriter
innerWriter io.WriteCloser
- formatter LogFormatter
- Formatter string `json:"formatter"`
ReconnectOnMsg bool `json:"reconnectOnMsg"`
Reconnect bool `json:"reconnect"`
Net string `json:"net"`
@@ -37,40 +33,23 @@ type connWriter struct {
Level int `json:"level"`
}
-// NewConn creates new ConnWrite returning as LoggerInterface.
+// NewConn create new ConnWrite returning as LoggerInterface.
func NewConn() Logger {
conn := new(connWriter)
conn.Level = LevelTrace
- conn.formatter = conn
return conn
}
-func (c *connWriter) Format(lm *LogMsg) string {
- return lm.OldStyleFormat()
+// Init init connection writer with json config.
+// json config only need key "level".
+func (c *connWriter) Init(jsonConfig string) error {
+ return json.Unmarshal([]byte(jsonConfig), c)
}
-// Init initializes a connection writer with json config.
-// json config only needs they "level" key
-func (c *connWriter) Init(config string) error {
- res := json.Unmarshal([]byte(config), c)
- if res == nil && len(c.Formatter) > 0 {
- fmtr, ok := GetFormatter(c.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", c.Formatter))
- }
- c.formatter = fmtr
- }
- return res
-}
-
-func (c *connWriter) SetFormatter(f LogFormatter) {
- c.formatter = f
-}
-
-// WriteMsg writes message in connection.
-// If connection is down, try to re-connect.
-func (c *connWriter) WriteMsg(lm *LogMsg) error {
- if lm.Level > c.Level {
+// WriteMsg write message in connection.
+// if connection is down, try to re-connect.
+func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
+ if level > c.Level {
return nil
}
if c.needToConnectOnMsg() {
@@ -84,12 +63,7 @@ func (c *connWriter) WriteMsg(lm *LogMsg) error {
defer c.innerWriter.Close()
}
- msg := c.formatter.Format(lm)
-
- _, err := c.lg.writeln(msg)
- if err != nil {
- return err
- }
+ c.lg.writeln(when, msg)
return nil
}
@@ -127,6 +101,7 @@ func (c *connWriter) connect() error {
func (c *connWriter) needToConnectOnMsg() bool {
if c.Reconnect {
+ c.Reconnect = false
return true
}
diff --git a/adapter/utils/caller.go b/logs/conn_test.go
similarity index 78%
rename from adapter/utils/caller.go
rename to logs/conn_test.go
index 419f11d6..747fb890 100644
--- a/adapter/utils/caller.go
+++ b/logs/conn_test.go
@@ -12,13 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package utils
+package logs
import (
- "github.com/astaxie/beego/core/utils"
+ "testing"
)
-// GetFuncName get function name
-func GetFuncName(i interface{}) string {
- return utils.GetFuncName(i)
+func TestConn(t *testing.T) {
+ log := NewLogger(1000)
+ log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`)
+ log.Informational("informational")
}
diff --git a/core/logs/console.go b/logs/console.go
similarity index 57%
rename from core/logs/console.go
rename to logs/console.go
index 66e2c7ea..3dcaee1d 100644
--- a/core/logs/console.go
+++ b/logs/console.go
@@ -16,18 +16,17 @@ package logs
import (
"encoding/json"
- "fmt"
"os"
"strings"
+ "time"
- "github.com/pkg/errors"
"github.com/shiena/ansicolor"
)
// brush is a color join function
type brush func(string) string
-// newBrush returns a fix color Brush
+// newBrush return a fix color Brush
func newBrush(color string) brush {
pre := "\033["
reset := "\033[0m"
@@ -49,68 +48,39 @@ var colors = []brush{
// consoleWriter implements LoggerInterface and writes messages to terminal.
type consoleWriter struct {
- lg *logWriter
- formatter LogFormatter
- Formatter string `json:"formatter"`
- Level int `json:"level"`
- Colorful bool `json:"color"` // this filed is useful only when system's terminal supports color
+ lg *logWriter
+ Level int `json:"level"`
+ Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
}
-func (c *consoleWriter) Format(lm *LogMsg) string {
- msg := lm.OldStyleFormat()
- if c.Colorful {
- msg = strings.Replace(msg, levelPrefix[lm.Level], colors[lm.Level](levelPrefix[lm.Level]), 1)
- }
- h, _, _ := formatTimeHeader(lm.When)
- bytes := append(append(h, msg...), '\n')
- return string(bytes)
-}
-
-func (c *consoleWriter) SetFormatter(f LogFormatter) {
- c.formatter = f
-}
-
-// NewConsole creates ConsoleWriter returning as LoggerInterface.
+// NewConsole create ConsoleWriter returning as LoggerInterface.
func NewConsole() Logger {
- return newConsole()
-}
-
-func newConsole() *consoleWriter {
cw := &consoleWriter{
lg: newLogWriter(ansicolor.NewAnsiColorWriter(os.Stdout)),
Level: LevelDebug,
Colorful: true,
}
- cw.formatter = cw
return cw
}
-// Init initianlizes the console logger.
-// jsonConfig must be in the format '{"level":LevelTrace}'
-func (c *consoleWriter) Init(config string) error {
-
- if len(config) == 0 {
+// Init init console logger.
+// jsonConfig like '{"level":LevelTrace}'.
+func (c *consoleWriter) Init(jsonConfig string) error {
+ if len(jsonConfig) == 0 {
return nil
}
-
- res := json.Unmarshal([]byte(config), c)
- if res == nil && len(c.Formatter) > 0 {
- fmtr, ok := GetFormatter(c.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", c.Formatter))
- }
- c.formatter = fmtr
- }
- return res
+ return json.Unmarshal([]byte(jsonConfig), c)
}
-// WriteMsg writes message in console.
-func (c *consoleWriter) WriteMsg(lm *LogMsg) error {
- if lm.Level > c.Level {
+// WriteMsg write message in console.
+func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
+ if level > c.Level {
return nil
}
- msg := c.formatter.Format(lm)
- c.lg.writeln(msg)
+ if c.Colorful {
+ msg = strings.Replace(msg, levelPrefix[level], colors[level](levelPrefix[level]), 1)
+ }
+ c.lg.writeln(when, msg)
return nil
}
diff --git a/core/logs/console_test.go b/logs/console_test.go
similarity index 78%
rename from core/logs/console_test.go
rename to logs/console_test.go
index e345ba40..4bc45f57 100644
--- a/core/logs/console_test.go
+++ b/logs/console_test.go
@@ -17,8 +17,6 @@ package logs
import (
"testing"
"time"
-
- "github.com/stretchr/testify/assert"
)
// Try each log level in decreasing order of priority.
@@ -64,19 +62,3 @@ func TestConsoleAsync(t *testing.T) {
time.Sleep(1 * time.Millisecond)
}
}
-
-func TestFormat(t *testing.T) {
- log := newConsole()
- lm := &LogMsg{
- Level: LevelDebug,
- Msg: "Hello, world",
- When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
- FilePath: "/user/home/main.go",
- LineNumber: 13,
- Prefix: "Cus",
- }
- res := log.Format(lm)
- assert.Equal(t, "2020/09/19 20:12:37.000 \x1b[1;44m[D]\x1b[0m Cus Hello, world\n", res)
- err := log.WriteMsg(lm)
- assert.Nil(t, err)
-}
diff --git a/core/logs/es/es.go b/logs/es/es.go
similarity index 56%
rename from core/logs/es/es.go
rename to logs/es/es.go
index 6175f253..2b7b1710 100644
--- a/core/logs/es/es.go
+++ b/logs/es/es.go
@@ -12,14 +12,13 @@ import (
"github.com/elastic/go-elasticsearch/v6"
"github.com/elastic/go-elasticsearch/v6/esapi"
- "github.com/astaxie/beego/core/logs"
+ "github.com/astaxie/beego/logs"
)
-// NewES returns a LoggerInterface
+// NewES return a LoggerInterface
func NewES() logs.Logger {
cw := &esLogger{
- Level: logs.LevelDebug,
- indexNaming: indexNaming,
+ Level: logs.LevelDebug,
}
return cw
}
@@ -32,36 +31,13 @@ func NewES() logs.Logger {
// import _ "github.com/astaxie/beego/logs/es"
type esLogger struct {
*elasticsearch.Client
- DSN string `json:"dsn"`
- Level int `json:"level"`
- formatter logs.LogFormatter
- Formatter string `json:"formatter"`
-
- indexNaming IndexNaming
-}
-
-func (el *esLogger) Format(lm *logs.LogMsg) string {
-
- msg := lm.OldStyleFormat()
- idx := LogDocument{
- Timestamp: lm.When.Format(time.RFC3339),
- Msg: msg,
- }
- body, err := json.Marshal(idx)
- if err != nil {
- return msg
- }
- return string(body)
-}
-
-func (el *esLogger) SetFormatter(f logs.LogFormatter) {
- el.formatter = f
+ DSN string `json:"dsn"`
+ Level int `json:"level"`
}
// {"dsn":"http://localhost:9200/","level":1}
-func (el *esLogger) Init(config string) error {
-
- err := json.Unmarshal([]byte(config), el)
+func (el *esLogger) Init(jsonconfig string) error {
+ err := json.Unmarshal([]byte(jsonconfig), el)
if err != nil {
return err
}
@@ -80,30 +56,30 @@ func (el *esLogger) Init(config string) error {
}
el.Client = conn
}
- if len(el.Formatter) > 0 {
- fmtr, ok := logs.GetFormatter(el.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", el.Formatter))
- }
- el.formatter = fmtr
- }
return nil
}
-// WriteMsg writes the msg and level into es
-func (el *esLogger) WriteMsg(lm *logs.LogMsg) error {
- if lm.Level > el.Level {
+// WriteMsg will write the msg and level into es
+func (el *esLogger) WriteMsg(when time.Time, msg string, level int) error {
+ if level > el.Level {
return nil
}
- msg := el.formatter.Format(lm)
-
- req := esapi.IndexRequest{
- Index: indexNaming.IndexName(lm),
- DocumentType: "logs",
- Body: strings.NewReader(msg),
+ idx := LogDocument{
+ Timestamp: when.Format(time.RFC3339),
+ Msg: msg,
}
- _, err := req.Do(context.Background(), el.Client)
+
+ body, err := json.Marshal(idx)
+ if err != nil {
+ return err
+ }
+ req := esapi.IndexRequest{
+ Index: fmt.Sprintf("%04d.%02d.%02d", when.Year(), when.Month(), when.Day()),
+ DocumentType: "logs",
+ Body: strings.NewReader(string(body)),
+ }
+ _, err = req.Do(context.Background(), el.Client)
return err
}
diff --git a/core/logs/file.go b/logs/file.go
similarity index 80%
rename from core/logs/file.go
rename to logs/file.go
index b01be357..222db989 100644
--- a/core/logs/file.go
+++ b/logs/file.go
@@ -30,7 +30,7 @@ import (
)
// fileLogWriter implements LoggerInterface.
-// Writes messages by lines limit, file size limit, or time frequency.
+// It writes messages by lines limit, file size limit, or time frequency.
type fileLogWriter struct {
sync.RWMutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize
// The opened file
@@ -69,12 +69,9 @@ type fileLogWriter struct {
RotatePerm string `json:"rotateperm"`
fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix
-
- formatter LogFormatter
- Formatter string `json:"formatter"`
}
-// newFileWriter creates a FileLogWriter returning as LoggerInterface.
+// newFileWriter create a FileLogWriter returning as LoggerInterface.
func newFileWriter() Logger {
w := &fileLogWriter{
Daily: true,
@@ -89,21 +86,9 @@ func newFileWriter() Logger {
MaxFiles: 999,
MaxSize: 1 << 28,
}
- w.formatter = w
return w
}
-func (w *fileLogWriter) Format(lm *LogMsg) string {
- msg := lm.OldStyleFormat()
- hd, _, _ := formatTimeHeader(lm.When)
- msg = fmt.Sprintf("%s %s\n", string(hd), msg)
- return msg
-}
-
-func (w *fileLogWriter) SetFormatter(f LogFormatter) {
- w.formatter = f
-}
-
// Init file logger with json config.
// jsonConfig like:
// {
@@ -115,9 +100,8 @@ func (w *fileLogWriter) SetFormatter(f LogFormatter) {
// "rotate":true,
// "perm":"0600"
// }
-func (w *fileLogWriter) Init(config string) error {
-
- err := json.Unmarshal([]byte(config), w)
+func (w *fileLogWriter) Init(jsonConfig string) error {
+ err := json.Unmarshal([]byte(jsonConfig), w)
if err != nil {
return err
}
@@ -129,14 +113,6 @@ func (w *fileLogWriter) Init(config string) error {
if w.suffix == "" {
w.suffix = ".log"
}
-
- if len(w.Formatter) > 0 {
- fmtr, ok := GetFormatter(w.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", w.Formatter))
- }
- w.formatter = fmtr
- }
err = w.startLogger()
return err
}
@@ -154,44 +130,42 @@ func (w *fileLogWriter) startLogger() error {
return w.initFd()
}
-func (w *fileLogWriter) needRotateDaily(day int) bool {
+func (w *fileLogWriter) needRotateDaily(size int, day int) bool {
return (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) ||
(w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) ||
(w.Daily && day != w.dailyOpenDate)
}
-func (w *fileLogWriter) needRotateHourly(hour int) bool {
+func (w *fileLogWriter) needRotateHourly(size int, hour int) bool {
return (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) ||
(w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) ||
(w.Hourly && hour != w.hourlyOpenDate)
}
-// WriteMsg writes logger message into file.
-func (w *fileLogWriter) WriteMsg(lm *LogMsg) error {
- if lm.Level > w.Level {
+// WriteMsg write logger message into file.
+func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
+ if level > w.Level {
return nil
}
-
- _, d, h := formatTimeHeader(lm.When)
-
- msg := w.formatter.Format(lm)
+ hd, d, h := formatTimeHeader(when)
+ msg = string(hd) + msg + "\n"
if w.Rotate {
w.RLock()
- if w.needRotateHourly(h) {
+ if w.needRotateHourly(len(msg), h) {
w.RUnlock()
w.Lock()
- if w.needRotateHourly(h) {
- if err := w.doRotate(lm.When); err != nil {
+ if w.needRotateHourly(len(msg), h) {
+ if err := w.doRotate(when); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
}
w.Unlock()
- } else if w.needRotateDaily(d) {
+ } else if w.needRotateDaily(len(msg), d) {
w.RUnlock()
w.Lock()
- if w.needRotateDaily(d) {
- if err := w.doRotate(lm.When); err != nil {
+ if w.needRotateDaily(len(msg), d) {
+ if err := w.doRotate(when); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
}
@@ -262,7 +236,7 @@ func (w *fileLogWriter) dailyRotate(openTime time.Time) {
tm := time.NewTimer(time.Duration(nextDay.UnixNano() - openTime.UnixNano() + 100))
<-tm.C
w.Lock()
- if w.needRotateDaily(time.Now().Day()) {
+ if w.needRotateDaily(0, time.Now().Day()) {
if err := w.doRotate(time.Now()); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
@@ -277,7 +251,7 @@ func (w *fileLogWriter) hourlyRotate(openTime time.Time) {
tm := time.NewTimer(time.Duration(nextHour.UnixNano() - openTime.UnixNano() + 100))
<-tm.C
w.Lock()
- if w.needRotateHourly(time.Now().Hour()) {
+ if w.needRotateHourly(0, time.Now().Hour()) {
if err := w.doRotate(time.Now()); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
@@ -312,7 +286,7 @@ func (w *fileLogWriter) lines() (int, error) {
return count, nil
}
-// DoRotate means it needs to write logs into a new file.
+// DoRotate means it need to write file in new file.
// new file name like xx.2013-01-01.log (daily) or xx.001.log (by line or size)
func (w *fileLogWriter) doRotate(logTime time.Time) error {
// file exists
@@ -328,7 +302,7 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error {
_, err = os.Lstat(w.Filename)
if err != nil {
- // even if the file is not exist or other ,we should RESTART the logger
+ //even if the file is not exist or other ,we should RESTART the logger
goto RESTART_LOGGER
}
@@ -399,21 +373,21 @@ func (w *fileLogWriter) deleteOldLog() {
if info == nil {
return
}
- if w.Hourly {
- if !info.IsDir() && info.ModTime().Add(1*time.Hour*time.Duration(w.MaxHours)).Before(time.Now()) {
- if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) &&
- strings.HasSuffix(filepath.Base(path), w.suffix) {
- os.Remove(path)
- }
- }
- } else if w.Daily {
- if !info.IsDir() && info.ModTime().Add(24*time.Hour*time.Duration(w.MaxDays)).Before(time.Now()) {
- if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) &&
- strings.HasSuffix(filepath.Base(path), w.suffix) {
- os.Remove(path)
- }
- }
- }
+ if w.Hourly {
+ if !info.IsDir() && info.ModTime().Add(1 * time.Hour * time.Duration(w.MaxHours)).Before(time.Now()) {
+ if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) &&
+ strings.HasSuffix(filepath.Base(path), w.suffix) {
+ os.Remove(path)
+ }
+ }
+ } else if w.Daily {
+ if !info.IsDir() && info.ModTime().Add(24 * time.Hour * time.Duration(w.MaxDays)).Before(time.Now()) {
+ if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) &&
+ strings.HasSuffix(filepath.Base(path), w.suffix) {
+ os.Remove(path)
+ }
+ }
+ }
return
})
}
@@ -423,7 +397,7 @@ func (w *fileLogWriter) Destroy() {
w.fileWriter.Close()
}
-// Flush flushes file logger.
+// Flush flush file logger.
// there are no buffering messages in file logger in memory.
// flush file means sync file from disk.
func (w *fileLogWriter) Flush() {
diff --git a/core/logs/file_test.go b/logs/file_test.go
similarity index 89%
rename from core/logs/file_test.go
rename to logs/file_test.go
index 6612ebe6..e7c2ca9a 100644
--- a/core/logs/file_test.go
+++ b/logs/file_test.go
@@ -22,8 +22,6 @@ import (
"strconv"
"testing"
"time"
-
- "github.com/stretchr/testify/assert"
)
func TestFilePerm(t *testing.T) {
@@ -188,7 +186,7 @@ func TestFileDailyRotate_06(t *testing.T) { //test file mode
func TestFileHourlyRotate_01(t *testing.T) {
log := NewLogger(10000)
- log.SetLogger("file", `{"filename":"test3.log","hourly":true,"maxlines":4}`)
+ log.SetLogger("file", `{"filename":"test3.log","hourly":true,"maxlines":4}`)
log.Debug("debug")
log.Info("info")
log.Notice("notice")
@@ -239,7 +237,7 @@ func TestFileHourlyRotate_05(t *testing.T) {
func TestFileHourlyRotate_06(t *testing.T) { //test file mode
log := NewLogger(10000)
- log.SetLogger("file", `{"filename":"test3.log", "hourly":true, "maxlines":4}`)
+ log.SetLogger("file", `{"filename":"test3.log", "hourly":true, "maxlines":4}`)
log.Debug("debug")
log.Info("info")
log.Notice("notice")
@@ -270,26 +268,20 @@ func testFileRotate(t *testing.T, fn1, fn2 string, daily, hourly bool) {
Perm: "0660",
RotatePerm: "0440",
}
- fw.formatter = fw
- if daily {
- fw.Init(fmt.Sprintf(`{"filename":"%v","maxdays":1}`, fn1))
- fw.dailyOpenTime = time.Now().Add(-24 * time.Hour)
- fw.dailyOpenDate = fw.dailyOpenTime.Day()
- }
+ if daily {
+ fw.Init(fmt.Sprintf(`{"filename":"%v","maxdays":1}`, fn1))
+ fw.dailyOpenTime = time.Now().Add(-24 * time.Hour)
+ fw.dailyOpenDate = fw.dailyOpenTime.Day()
+ }
- if hourly {
- fw.Init(fmt.Sprintf(`{"filename":"%v","maxhours":1}`, fn1))
- fw.hourlyOpenTime = time.Now().Add(-1 * time.Hour)
- fw.hourlyOpenDate = fw.hourlyOpenTime.Day()
- }
- lm := &LogMsg{
- Msg: "Test message",
- Level: LevelDebug,
- When: time.Now(),
- }
+ if hourly {
+ fw.Init(fmt.Sprintf(`{"filename":"%v","maxhours":1}`, fn1))
+ fw.hourlyOpenTime = time.Now().Add(-1 * time.Hour)
+ fw.hourlyOpenDate = fw.hourlyOpenTime.Day()
+ }
- fw.WriteMsg(lm)
+ fw.WriteMsg(time.Now(), "this is a msg for test", LevelDebug)
for _, file := range []string{fn1, fn2} {
_, err := os.Stat(file)
@@ -311,8 +303,6 @@ func testFileDailyRotate(t *testing.T, fn1, fn2 string) {
Perm: "0660",
RotatePerm: "0440",
}
- fw.formatter = fw
-
fw.Init(fmt.Sprintf(`{"filename":"%v","maxdays":1}`, fn1))
fw.dailyOpenTime = time.Now().Add(-24 * time.Hour)
fw.dailyOpenDate = fw.dailyOpenTime.Day()
@@ -338,15 +328,13 @@ func testFileDailyRotate(t *testing.T, fn1, fn2 string) {
func testFileHourlyRotate(t *testing.T, fn1, fn2 string) {
fw := &fileLogWriter{
- Hourly: true,
- MaxHours: 168,
+ Hourly: true,
+ MaxHours: 168,
Rotate: true,
Level: LevelTrace,
Perm: "0660",
RotatePerm: "0440",
}
-
- fw.formatter = fw
fw.Init(fmt.Sprintf(`{"filename":"%v","maxhours":1}`, fn1))
fw.hourlyOpenTime = time.Now().Add(-1 * time.Hour)
fw.hourlyOpenDate = fw.hourlyOpenTime.Hour()
@@ -430,18 +418,3 @@ func BenchmarkFileOnGoroutine(b *testing.B) {
}
os.Remove("test4.log")
}
-
-func TestFileLogWriter_Format(t *testing.T) {
- lg := &LogMsg{
- Level: LevelDebug,
- Msg: "Hello, world",
- When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
- FilePath: "/user/home/main.go",
- LineNumber: 13,
- Prefix: "Cus",
- }
-
- fw := newFileWriter().(*fileLogWriter)
- res := fw.Format(lg)
- assert.Equal(t, "2020/09/19 20:12:37.000 [D] Cus Hello, world\n", res)
-}
diff --git a/core/logs/jianliao.go b/logs/jianliao.go
similarity index 56%
rename from core/logs/jianliao.go
rename to logs/jianliao.go
index c82a0957..88ba0f9a 100644
--- a/core/logs/jianliao.go
+++ b/logs/jianliao.go
@@ -5,8 +5,7 @@ import (
"fmt"
"net/http"
"net/url"
-
- "github.com/pkg/errors"
+ "time"
)
// JLWriter implements beego LoggerInterface and is used to send jiaoliao webhook
@@ -17,50 +16,26 @@ type JLWriter struct {
RedirectURL string `json:"redirecturl,omitempty"`
ImageURL string `json:"imageurl,omitempty"`
Level int `json:"level"`
-
- formatter LogFormatter
- Formatter string `json:"formatter"`
}
-// newJLWriter creates jiaoliao writer.
+// newJLWriter create jiaoliao writer.
func newJLWriter() Logger {
- res := &JLWriter{Level: LevelTrace}
- res.formatter = res
- return res
+ return &JLWriter{Level: LevelTrace}
}
// Init JLWriter with json config string
-func (s *JLWriter) Init(config string) error {
-
- res := json.Unmarshal([]byte(config), s)
- if res == nil && len(s.Formatter) > 0 {
- fmtr, ok := GetFormatter(s.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", s.Formatter))
- }
- s.formatter = fmtr
- }
- return res
+func (s *JLWriter) Init(jsonconfig string) error {
+ return json.Unmarshal([]byte(jsonconfig), s)
}
-func (s *JLWriter) Format(lm *LogMsg) string {
- msg := lm.OldStyleFormat()
- msg = fmt.Sprintf("%s %s", lm.When.Format("2006-01-02 15:04:05"), msg)
- return msg
-}
-
-func (s *JLWriter) SetFormatter(f LogFormatter) {
- s.formatter = f
-}
-
-// WriteMsg writes message in smtp writer.
-// Sends an email with subject and only this message.
-func (s *JLWriter) WriteMsg(lm *LogMsg) error {
- if lm.Level > s.Level {
+// WriteMsg write message in smtp writer.
+// it will send an email with subject and only this message.
+func (s *JLWriter) WriteMsg(when time.Time, msg string, level int) error {
+ if level > s.Level {
return nil
}
- text := s.formatter.Format(lm)
+ text := fmt.Sprintf("%s %s", when.Format("2006-01-02 15:04:05"), msg)
form := url.Values{}
form.Add("authorName", s.AuthorName)
diff --git a/core/logs/log.go b/logs/log.go
similarity index 78%
rename from core/logs/log.go
rename to logs/log.go
index d5953dfb..39c006d2 100644
--- a/core/logs/log.go
+++ b/logs/log.go
@@ -37,12 +37,12 @@ import (
"fmt"
"log"
"os"
+ "path"
"runtime"
+ "strconv"
"strings"
"sync"
"time"
-
- "github.com/pkg/errors"
)
// RFC5424 log message levels.
@@ -86,10 +86,9 @@ type newLoggerFunc func() Logger
// Logger defines the behavior of a log provider.
type Logger interface {
Init(config string) error
- WriteMsg(lm *LogMsg) error
+ WriteMsg(when time.Time, msg string, level int) error
Destroy()
Flush()
- SetFormatter(f LogFormatter)
}
var adapters = make(map[string]newLoggerFunc)
@@ -109,22 +108,20 @@ func Register(name string, log newLoggerFunc) {
}
// BeeLogger is default logger in beego application.
-// Can contain several providers and log message into all providers.
+// it can contain several providers and log message into all providers.
type BeeLogger struct {
lock sync.Mutex
level int
init bool
enableFuncCallDepth bool
loggerFuncCallDepth int
- enableFullFilePath bool
asynchronous bool
prefix string
msgChanLen int64
- msgChan chan *LogMsg
+ msgChan chan *logMsg
signalChan chan string
wg sync.WaitGroup
outputs []*nameLogger
- globalFormatter string
}
const defaultAsyncMsgLen = 1e3
@@ -134,15 +131,21 @@ type nameLogger struct {
name string
}
+type logMsg struct {
+ level int
+ msg string
+ when time.Time
+}
+
var logMsgPool *sync.Pool
// NewLogger returns a new BeeLogger.
-// channelLen: the number of messages in chan(used where asynchronous is true).
+// channelLen means the number of messages in chan(used where asynchronous is true).
// if the buffering chan is full, logger adapters write to file or other way.
func NewLogger(channelLens ...int64) *BeeLogger {
bl := new(BeeLogger)
bl.level = LevelDebug
- bl.loggerFuncCallDepth = 3
+ bl.loggerFuncCallDepth = 2
bl.msgChanLen = append(channelLens, 0)[0]
if bl.msgChanLen <= 0 {
bl.msgChanLen = defaultAsyncMsgLen
@@ -152,7 +155,7 @@ func NewLogger(channelLens ...int64) *BeeLogger {
return bl
}
-// Async sets the log to asynchronous and start the goroutine
+// Async set the log to asynchronous and start the goroutine
func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
bl.lock.Lock()
defer bl.lock.Unlock()
@@ -163,10 +166,10 @@ func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
if len(msgLen) > 0 && msgLen[0] > 0 {
bl.msgChanLen = msgLen[0]
}
- bl.msgChan = make(chan *LogMsg, bl.msgChanLen)
+ bl.msgChan = make(chan *logMsg, bl.msgChanLen)
logMsgPool = &sync.Pool{
New: func() interface{} {
- return &LogMsg{}
+ return &logMsg{}
},
}
bl.wg.Add(1)
@@ -175,7 +178,7 @@ func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
}
// SetLogger provides a given logger adapter into BeeLogger with config string.
-// config must in in JSON format like {"interval":360}}
+// config need to be correct JSON as string: {"interval":360}.
func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
config := append(configs, "{}")[0]
for _, l := range bl.outputs {
@@ -190,18 +193,7 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
}
lg := logAdapter()
-
- // Global formatter overrides the default set formatter
- if len(bl.globalFormatter) > 0 {
- fmtr, ok := GetFormatter(bl.globalFormatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", bl.globalFormatter))
- }
- lg.SetFormatter(fmtr)
- }
-
err := lg.Init(config)
-
if err != nil {
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
return err
@@ -211,7 +203,7 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
}
// SetLogger provides a given logger adapter into BeeLogger with config string.
-// config must in in JSON format like {"interval":360}}
+// config need to be correct JSON as string: {"interval":360}.
func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
bl.lock.Lock()
defer bl.lock.Unlock()
@@ -222,7 +214,7 @@ func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
return bl.setLogger(adapterName, configs...)
}
-// DelLogger removes a logger adapter in BeeLogger.
+// DelLogger remove a logger adapter in BeeLogger.
func (bl *BeeLogger) DelLogger(adapterName string) error {
bl.lock.Lock()
defer bl.lock.Unlock()
@@ -241,9 +233,9 @@ func (bl *BeeLogger) DelLogger(adapterName string) error {
return nil
}
-func (bl *BeeLogger) writeToLoggers(lm *LogMsg) {
+func (bl *BeeLogger) writeToLoggers(when time.Time, msg string, level int) {
for _, l := range bl.outputs {
- err := l.WriteMsg(lm)
+ err := l.WriteMsg(when, msg, level)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err)
}
@@ -258,72 +250,65 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) {
if p[len(p)-1] == '\n' {
p = p[0 : len(p)-1]
}
- lm := &LogMsg{
- Msg: string(p),
- Level: levelLoggerImpl,
- }
-
// set levelLoggerImpl to ensure all log message will be write out
- err = bl.writeMsg(lm)
+ err = bl.writeMsg(levelLoggerImpl, string(p))
if err == nil {
return len(p), err
}
return 0, err
}
-func (bl *BeeLogger) writeMsg(lm *LogMsg) error {
+func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error {
if !bl.init {
bl.lock.Lock()
bl.setLogger(AdapterConsole)
bl.lock.Unlock()
}
- var (
- file string
- line int
- ok bool
- )
-
- _, file, line, ok = runtime.Caller(bl.loggerFuncCallDepth)
- if !ok {
- file = "???"
- line = 0
+ if len(v) > 0 {
+ msg = fmt.Sprintf(msg, v...)
}
- lm.FilePath = file
- lm.LineNumber = line
- lm.enableFullFilePath = bl.enableFullFilePath
- lm.enableFuncCallDepth = bl.enableFuncCallDepth
+ msg = bl.prefix + " " + msg
- // set level info in front of filename info
- if lm.Level == levelLoggerImpl {
+ when := time.Now()
+ if bl.enableFuncCallDepth {
+ _, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth)
+ if !ok {
+ file = "???"
+ line = 0
+ }
+ _, filename := path.Split(file)
+ msg = "[" + filename + ":" + strconv.Itoa(line) + "] " + msg
+ }
+
+ //set level info in front of filename info
+ if logLevel == levelLoggerImpl {
// set to emergency to ensure all log will be print out correctly
- lm.Level = LevelEmergency
+ logLevel = LevelEmergency
+ } else {
+ msg = levelPrefix[logLevel] + " " + msg
}
if bl.asynchronous {
- logM := logMsgPool.Get().(*LogMsg)
- logM.Level = lm.Level
- logM.Msg = lm.Msg
- logM.When = lm.When
- logM.Args = lm.Args
- logM.FilePath = lm.FilePath
- logM.LineNumber = lm.LineNumber
- logM.Prefix = lm.Prefix
+ lm := logMsgPool.Get().(*logMsg)
+ lm.level = logLevel
+ lm.msg = msg
+ lm.when = when
if bl.outputs != nil {
bl.msgChan <- lm
} else {
logMsgPool.Put(lm)
}
} else {
- bl.writeToLoggers(lm)
+ bl.writeToLoggers(when, msg, logLevel)
}
return nil
}
-// SetLevel sets log message level.
+// SetLevel Set log message level.
// If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
-// log providers will not be sent the message.
+// log providers will not even be sent the message.
func (bl *BeeLogger) SetLevel(l int) {
bl.level = l
}
@@ -360,7 +345,7 @@ func (bl *BeeLogger) startLogger() {
for {
select {
case bm := <-bl.msgChan:
- bl.writeToLoggers(bm)
+ bl.writeToLoggers(bm.when, bm.msg, bm.level)
logMsgPool.Put(bm)
case sg := <-bl.signalChan:
// Now should only send "flush" or "close" to bl.signalChan
@@ -380,33 +365,12 @@ func (bl *BeeLogger) startLogger() {
}
}
-func (bl *BeeLogger) setGlobalFormatter(fmtter string) error {
- bl.globalFormatter = fmtter
- return nil
-}
-
-// SetGlobalFormatter sets the global formatter for all log adapters
-// don't forget to register the formatter by invoking RegisterFormatter
-func SetGlobalFormatter(fmtter string) error {
- return beeLogger.setGlobalFormatter(fmtter)
-}
-
// Emergency Log EMERGENCY level message.
func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
if LevelEmergency > bl.level {
return
}
-
- lm := &LogMsg{
- Level: LevelEmergency,
- Msg: format,
- When: time.Now(),
- }
- if len(v) > 0 {
- lm.Msg = fmt.Sprintf(lm.Msg, v...)
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelEmergency, format, v...)
}
// Alert Log ALERT level message.
@@ -414,14 +378,7 @@ func (bl *BeeLogger) Alert(format string, v ...interface{}) {
if LevelAlert > bl.level {
return
}
-
- lm := &LogMsg{
- Level: LevelAlert,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
- bl.writeMsg(lm)
+ bl.writeMsg(LevelAlert, format, v...)
}
// Critical Log CRITICAL level message.
@@ -429,14 +386,7 @@ func (bl *BeeLogger) Critical(format string, v ...interface{}) {
if LevelCritical > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelCritical,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelCritical, format, v...)
}
// Error Log ERROR level message.
@@ -444,14 +394,7 @@ func (bl *BeeLogger) Error(format string, v ...interface{}) {
if LevelError > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelError,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelError, format, v...)
}
// Warning Log WARNING level message.
@@ -459,14 +402,7 @@ func (bl *BeeLogger) Warning(format string, v ...interface{}) {
if LevelWarn > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelWarn,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelWarn, format, v...)
}
// Notice Log NOTICE level message.
@@ -474,14 +410,7 @@ func (bl *BeeLogger) Notice(format string, v ...interface{}) {
if LevelNotice > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelNotice,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelNotice, format, v...)
}
// Informational Log INFORMATIONAL level message.
@@ -489,14 +418,7 @@ func (bl *BeeLogger) Informational(format string, v ...interface{}) {
if LevelInfo > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelInfo,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelInfo, format, v...)
}
// Debug Log DEBUG level message.
@@ -504,14 +426,7 @@ func (bl *BeeLogger) Debug(format string, v ...interface{}) {
if LevelDebug > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelDebug,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelDebug, format, v...)
}
// Warn Log WARN level message.
@@ -520,14 +435,7 @@ func (bl *BeeLogger) Warn(format string, v ...interface{}) {
if LevelWarn > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelWarn,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelWarn, format, v...)
}
// Info Log INFO level message.
@@ -536,14 +444,7 @@ func (bl *BeeLogger) Info(format string, v ...interface{}) {
if LevelInfo > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelInfo,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelInfo, format, v...)
}
// Trace Log TRACE level message.
@@ -552,14 +453,7 @@ func (bl *BeeLogger) Trace(format string, v ...interface{}) {
if LevelDebug > bl.level {
return
}
- lm := &LogMsg{
- Level: LevelDebug,
- Msg: format,
- When: time.Now(),
- Args: v,
- }
-
- bl.writeMsg(lm)
+ bl.writeMsg(LevelDebug, format, v...)
}
// Flush flush all chan data.
@@ -603,7 +497,7 @@ func (bl *BeeLogger) flush() {
for {
if len(bl.msgChan) > 0 {
bm := <-bl.msgChan
- bl.writeToLoggers(bm)
+ bl.writeToLoggers(bm.when, bm.msg, bm.level)
logMsgPool.Put(bm)
continue
}
@@ -653,12 +547,6 @@ func GetLogger(prefixes ...string) *log.Logger {
return l
}
-// EnableFullFilePath enables full file path logging. Disabled by default
-// e.g "/home/Documents/GitHub/beego/mainapp/" instead of "mainapp"
-func EnableFullFilePath(b bool) {
- beeLogger.enableFullFilePath = b
-}
-
// Reset will remove all the adapter
func Reset() {
beeLogger.Reset()
@@ -687,7 +575,7 @@ func EnableFuncCallDepth(b bool) {
// SetLogFuncCall set the CallDepth, default is 4
func SetLogFuncCall(b bool) {
beeLogger.EnableFuncCallDepth(b)
- beeLogger.SetLogFuncCallDepth(3)
+ beeLogger.SetLogFuncCallDepth(4)
}
// SetLogFuncCallDepth set log funcCallDepth
@@ -765,9 +653,9 @@ func formatLog(f interface{}, v ...interface{}) string {
return msg
}
if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") {
- // format string
+ //format string
} else {
- // do not contain format char
+ //do not contain format char
msg += strings.Repeat(" %v", len(v))
}
default:
diff --git a/core/logs/logger.go b/logs/logger.go
similarity index 96%
rename from core/logs/logger.go
rename to logs/logger.go
index d8b334d4..c7cf8a56 100644
--- a/core/logs/logger.go
+++ b/logs/logger.go
@@ -30,12 +30,11 @@ func newLogWriter(wr io.Writer) *logWriter {
return &logWriter{writer: wr}
}
-func (lg *logWriter) writeln(msg string) (int, error) {
+func (lg *logWriter) writeln(when time.Time, msg string) {
lg.Lock()
- msg += "\n"
- n, err := lg.writer.Write([]byte(msg))
+ h, _, _ := formatTimeHeader(when)
+ lg.writer.Write(append(append(h, msg...), '\n'))
lg.Unlock()
- return n, err
}
const (
diff --git a/core/logs/logger_test.go b/logs/logger_test.go
similarity index 100%
rename from core/logs/logger_test.go
rename to logs/logger_test.go
diff --git a/core/logs/multifile.go b/logs/multifile.go
similarity index 83%
rename from core/logs/multifile.go
rename to logs/multifile.go
index 79178211..90168274 100644
--- a/core/logs/multifile.go
+++ b/logs/multifile.go
@@ -16,6 +16,7 @@ package logs
import (
"encoding/json"
+ "time"
)
// A filesLogWriter manages several fileLogWriter
@@ -45,7 +46,6 @@ var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning
// }
func (f *multiFileLogWriter) Init(config string) error {
-
writer := newFileWriter().(*fileLogWriter)
err := writer.Init(config)
if err != nil {
@@ -54,17 +54,11 @@ func (f *multiFileLogWriter) Init(config string) error {
f.fullLogWriter = writer
f.writers[LevelDebug+1] = writer
- // unmarshal "separate" field to f.Separate
- err = json.Unmarshal([]byte(config), f)
- if err != nil {
- return err
- }
+ //unmarshal "separate" field to f.Separate
+ json.Unmarshal([]byte(config), f)
jsonMap := map[string]interface{}{}
- err = json.Unmarshal([]byte(config), &jsonMap)
- if err != nil {
- return err
- }
+ json.Unmarshal([]byte(config), &jsonMap)
for i := LevelEmergency; i < LevelDebug+1; i++ {
for _, v := range f.Separate {
@@ -81,17 +75,10 @@ func (f *multiFileLogWriter) Init(config string) error {
}
}
}
+
return nil
}
-func (f *multiFileLogWriter) Format(lm *LogMsg) string {
- return lm.OldStyleFormat()
-}
-
-func (f *multiFileLogWriter) SetFormatter(fmt LogFormatter) {
- f.fullLogWriter.SetFormatter(f)
-}
-
func (f *multiFileLogWriter) Destroy() {
for i := 0; i < len(f.writers); i++ {
if f.writers[i] != nil {
@@ -100,14 +87,14 @@ func (f *multiFileLogWriter) Destroy() {
}
}
-func (f *multiFileLogWriter) WriteMsg(lm *LogMsg) error {
+func (f *multiFileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
if f.fullLogWriter != nil {
- f.fullLogWriter.WriteMsg(lm)
+ f.fullLogWriter.WriteMsg(when, msg, level)
}
for i := 0; i < len(f.writers)-1; i++ {
if f.writers[i] != nil {
- if lm.Level == f.writers[i].Level {
- f.writers[i].WriteMsg(lm)
+ if level == f.writers[i].Level {
+ f.writers[i].WriteMsg(when, msg, level)
}
}
}
@@ -124,8 +111,7 @@ func (f *multiFileLogWriter) Flush() {
// newFilesWriter create a FileLogWriter returning as LoggerInterface.
func newFilesWriter() Logger {
- res := &multiFileLogWriter{}
- return res
+ return &multiFileLogWriter{}
}
func init() {
diff --git a/core/logs/multifile_test.go b/logs/multifile_test.go
similarity index 100%
rename from core/logs/multifile_test.go
rename to logs/multifile_test.go
diff --git a/logs/slack.go b/logs/slack.go
new file mode 100644
index 00000000..1cd2e5ae
--- /dev/null
+++ b/logs/slack.go
@@ -0,0 +1,60 @@
+package logs
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "net/url"
+ "time"
+)
+
+// SLACKWriter implements beego LoggerInterface and is used to send jiaoliao webhook
+type SLACKWriter struct {
+ WebhookURL string `json:"webhookurl"`
+ Level int `json:"level"`
+}
+
+// newSLACKWriter create jiaoliao writer.
+func newSLACKWriter() Logger {
+ return &SLACKWriter{Level: LevelTrace}
+}
+
+// Init SLACKWriter with json config string
+func (s *SLACKWriter) Init(jsonconfig string) error {
+ return json.Unmarshal([]byte(jsonconfig), s)
+}
+
+// WriteMsg write message in smtp writer.
+// it will send an email with subject and only this message.
+func (s *SLACKWriter) WriteMsg(when time.Time, msg string, level int) error {
+ if level > s.Level {
+ return nil
+ }
+
+ text := fmt.Sprintf("{\"text\": \"%s %s\"}", when.Format("2006-01-02 15:04:05"), msg)
+
+ form := url.Values{}
+ form.Add("payload", text)
+
+ resp, err := http.PostForm(s.WebhookURL, form)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("Post webhook failed %s %d", resp.Status, resp.StatusCode)
+ }
+ return nil
+}
+
+// Flush implementing method. empty.
+func (s *SLACKWriter) Flush() {
+}
+
+// Destroy implementing method. empty.
+func (s *SLACKWriter) Destroy() {
+}
+
+func init() {
+ Register(AdapterSlack, newSLACKWriter)
+}
diff --git a/core/logs/smtp.go b/logs/smtp.go
similarity index 77%
rename from core/logs/smtp.go
rename to logs/smtp.go
index 40891a7c..6208d7b8 100644
--- a/core/logs/smtp.go
+++ b/logs/smtp.go
@@ -21,8 +21,7 @@ import (
"net"
"net/smtp"
"strings"
-
- "github.com/pkg/errors"
+ "time"
)
// SMTPWriter implements LoggerInterface and is used to send emails via given SMTP-server.
@@ -34,15 +33,11 @@ type SMTPWriter struct {
FromAddress string `json:"fromAddress"`
RecipientAddresses []string `json:"sendTos"`
Level int `json:"level"`
- formatter LogFormatter
- Formatter string `json:"formatter"`
}
-// NewSMTPWriter creates the smtp writer.
+// NewSMTPWriter create smtp writer.
func newSMTPWriter() Logger {
- res := &SMTPWriter{Level: LevelTrace}
- res.formatter = res
- return res
+ return &SMTPWriter{Level: LevelTrace}
}
// Init smtp writer with json config.
@@ -56,16 +51,8 @@ func newSMTPWriter() Logger {
// "sendTos":["email1","email2"],
// "level":LevelError
// }
-func (s *SMTPWriter) Init(config string) error {
- res := json.Unmarshal([]byte(config), s)
- if res == nil && len(s.Formatter) > 0 {
- fmtr, ok := GetFormatter(s.Formatter)
- if !ok {
- return errors.New(fmt.Sprintf("the formatter with name: %s not found", s.Formatter))
- }
- s.formatter = fmtr
- }
- return res
+func (s *SMTPWriter) Init(jsonconfig string) error {
+ return json.Unmarshal([]byte(jsonconfig), s)
}
func (s *SMTPWriter) getSMTPAuth(host string) smtp.Auth {
@@ -80,10 +67,6 @@ func (s *SMTPWriter) getSMTPAuth(host string) smtp.Auth {
)
}
-func (s *SMTPWriter) SetFormatter(f LogFormatter) {
- s.formatter = f
-}
-
func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAddress string, recipients []string, msgContent []byte) error {
client, err := smtp.Dial(hostAddressWithPort)
if err != nil {
@@ -132,14 +115,10 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd
return client.Quit()
}
-func (s *SMTPWriter) Format(lm *LogMsg) string {
- return lm.OldStyleFormat()
-}
-
-// WriteMsg writes message in smtp writer.
-// Sends an email with subject and only this message.
-func (s *SMTPWriter) WriteMsg(lm *LogMsg) error {
- if lm.Level > s.Level {
+// WriteMsg write message in smtp writer.
+// it will send an email with subject and only this message.
+func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
+ if level > s.Level {
return nil
}
@@ -148,13 +127,11 @@ func (s *SMTPWriter) WriteMsg(lm *LogMsg) error {
// Set up authentication information.
auth := s.getSMTPAuth(hp[0])
- msg := s.Format(lm)
-
// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
contentType := "Content-Type: text/plain" + "; charset=UTF-8"
mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.FromAddress + "<" + s.FromAddress +
- ">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", lm.When.Format("2006-01-02 15:04:05")) + msg)
+ ">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", when.Format("2006-01-02 15:04:05")) + msg)
return s.sendMail(s.Host, auth, s.FromAddress, s.RecipientAddresses, mailmsg)
}
diff --git a/core/logs/smtp_test.go b/logs/smtp_test.go
similarity index 100%
rename from core/logs/smtp_test.go
rename to logs/smtp_test.go
diff --git a/adapter/metric/prometheus.go b/metric/prometheus.go
similarity index 87%
rename from adapter/metric/prometheus.go
rename to metric/prometheus.go
index 4660f626..7722240b 100644
--- a/adapter/metric/prometheus.go
+++ b/metric/prometheus.go
@@ -24,8 +24,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/astaxie/beego"
- "github.com/astaxie/beego/core/logs"
- "github.com/astaxie/beego/server/web"
+ "github.com/astaxie/beego/logs"
)
func PrometheusMiddleWare(next http.Handler) http.Handler {
@@ -33,9 +32,9 @@ func PrometheusMiddleWare(next http.Handler) http.Handler {
Name: "beego",
Subsystem: "http_request",
ConstLabels: map[string]string{
- "server": web.BConfig.ServerName,
- "env": web.BConfig.RunMode,
- "appname": web.BConfig.AppName,
+ "server": beego.BConfig.ServerName,
+ "env": beego.BConfig.RunMode,
+ "appname": beego.BConfig.AppName,
},
Help: "The statics info for http request",
}, []string{"pattern", "method", "status", "duration"})
@@ -58,15 +57,15 @@ func registerBuildInfo() {
Subsystem: "build_info",
Help: "The building information",
ConstLabels: map[string]string{
- "appname": web.BConfig.AppName,
+ "appname": beego.BConfig.AppName,
"build_version": beego.BuildVersion,
"build_revision": beego.BuildGitRevision,
"build_status": beego.BuildStatus,
"build_tag": beego.BuildTag,
- "build_time": strings.Replace(beego.BuildTime, "--", " ", 1),
+ "build_time": strings.Replace(beego.BuildTime, "--", " ", 1),
"go_version": beego.GoVersion,
"git_branch": beego.GitBranch,
- "start_time": time.Now().Format("2006-01-02 15:04:05"),
+ "start_time": time.Now().Format("2006-01-02 15:04:05"),
},
}, []string{})
@@ -75,7 +74,7 @@ func registerBuildInfo() {
}
func report(dur time.Duration, writer http.ResponseWriter, q *http.Request, vec *prometheus.SummaryVec) {
- ctrl := web.BeeApp.Handlers
+ ctrl := beego.BeeApp.Handlers
ctx := ctrl.GetContext()
ctx.Reset(writer, q)
defer ctrl.GiveBackContext(ctx)
diff --git a/adapter/metric/prometheus_test.go b/metric/prometheus_test.go
similarity index 96%
rename from adapter/metric/prometheus_test.go
rename to metric/prometheus_test.go
index 751348bf..d82a6dec 100644
--- a/adapter/metric/prometheus_test.go
+++ b/metric/prometheus_test.go
@@ -22,7 +22,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
- "github.com/astaxie/beego/adapter/context"
+ "github.com/astaxie/beego/context"
)
func TestPrometheusMiddleWare(t *testing.T) {
diff --git a/client/orm/migration/ddl.go b/migration/ddl.go
similarity index 85%
rename from client/orm/migration/ddl.go
rename to migration/ddl.go
index a396d39a..cd2c1c49 100644
--- a/client/orm/migration/ddl.go
+++ b/migration/ddl.go
@@ -17,7 +17,7 @@ package migration
import (
"fmt"
- "github.com/astaxie/beego/core/logs"
+ "github.com/astaxie/beego/logs"
)
// Index struct defines the structure of Index Columns
@@ -31,7 +31,7 @@ type Unique struct {
Columns []*Column
}
-// Column struct defines a single column of a table
+//Column struct defines a single column of a table
type Column struct {
Name string
Inc string
@@ -84,7 +84,7 @@ func (m *Migration) NewCol(name string) *Column {
return col
}
-// PriCol creates a new primary column and attaches it to m struct
+//PriCol creates a new primary column and attaches it to m struct
func (m *Migration) PriCol(name string) *Column {
col := &Column{Name: name}
m.AddColumns(col)
@@ -92,7 +92,7 @@ func (m *Migration) PriCol(name string) *Column {
return col
}
-// UniCol creates / appends columns to specified unique key and attaches it to m struct
+//UniCol creates / appends columns to specified unique key and attaches it to m struct
func (m *Migration) UniCol(uni, name string) *Column {
col := &Column{Name: name}
m.AddColumns(col)
@@ -114,7 +114,7 @@ func (m *Migration) UniCol(uni, name string) *Column {
return col
}
-// ForeignCol creates a new foreign column and returns the instance of column
+//ForeignCol creates a new foreign column and returns the instance of column
func (m *Migration) ForeignCol(colname, foreigncol, foreigntable string) (foreign *Foreign) {
foreign = &Foreign{ForeignColumn: foreigncol, ForeignTable: foreigntable}
@@ -123,25 +123,25 @@ func (m *Migration) ForeignCol(colname, foreigncol, foreigntable string) (foreig
return foreign
}
-// SetOnDelete sets the on delete of foreign
+//SetOnDelete sets the on delete of foreign
func (foreign *Foreign) SetOnDelete(del string) *Foreign {
foreign.OnDelete = "ON DELETE" + del
return foreign
}
-// SetOnUpdate sets the on update of foreign
+//SetOnUpdate sets the on update of foreign
func (foreign *Foreign) SetOnUpdate(update string) *Foreign {
foreign.OnUpdate = "ON UPDATE" + update
return foreign
}
-// Remove marks the columns to be removed.
-// it allows reverse m to create the column.
+//Remove marks the columns to be removed.
+//it allows reverse m to create the column.
func (c *Column) Remove() {
c.remove = true
}
-// SetAuto enables auto_increment of column (can be used once)
+//SetAuto enables auto_increment of column (can be used once)
func (c *Column) SetAuto(inc bool) *Column {
if inc {
c.Inc = "auto_increment"
@@ -149,7 +149,7 @@ func (c *Column) SetAuto(inc bool) *Column {
return c
}
-// SetNullable sets the column to be null
+//SetNullable sets the column to be null
func (c *Column) SetNullable(null bool) *Column {
if null {
c.Null = ""
@@ -160,13 +160,13 @@ func (c *Column) SetNullable(null bool) *Column {
return c
}
-// SetDefault sets the default value, prepend with "DEFAULT "
+//SetDefault sets the default value, prepend with "DEFAULT "
func (c *Column) SetDefault(def string) *Column {
c.Default = "DEFAULT " + def
return c
}
-// SetUnsigned sets the column to be unsigned int
+//SetUnsigned sets the column to be unsigned int
func (c *Column) SetUnsigned(unsign bool) *Column {
if unsign {
c.Unsign = "UNSIGNED"
@@ -174,13 +174,13 @@ func (c *Column) SetUnsigned(unsign bool) *Column {
return c
}
-// SetDataType sets the dataType of the column
+//SetDataType sets the dataType of the column
func (c *Column) SetDataType(dataType string) *Column {
c.DataType = dataType
return c
}
-// SetOldNullable allows reverting to previous nullable on reverse ms
+//SetOldNullable allows reverting to previous nullable on reverse ms
func (c *RenameColumn) SetOldNullable(null bool) *RenameColumn {
if null {
c.OldNull = ""
@@ -191,13 +191,13 @@ func (c *RenameColumn) SetOldNullable(null bool) *RenameColumn {
return c
}
-// SetOldDefault allows reverting to previous default on reverse ms
+//SetOldDefault allows reverting to previous default on reverse ms
func (c *RenameColumn) SetOldDefault(def string) *RenameColumn {
c.OldDefault = def
return c
}
-// SetOldUnsigned allows reverting to previous unsgined on reverse ms
+//SetOldUnsigned allows reverting to previous unsgined on reverse ms
func (c *RenameColumn) SetOldUnsigned(unsign bool) *RenameColumn {
if unsign {
c.OldUnsign = "UNSIGNED"
@@ -205,19 +205,19 @@ func (c *RenameColumn) SetOldUnsigned(unsign bool) *RenameColumn {
return c
}
-// SetOldDataType allows reverting to previous datatype on reverse ms
+//SetOldDataType allows reverting to previous datatype on reverse ms
func (c *RenameColumn) SetOldDataType(dataType string) *RenameColumn {
c.OldDataType = dataType
return c
}
-// SetPrimary adds the columns to the primary key (can only be used any number of times in only one m)
+//SetPrimary adds the columns to the primary key (can only be used any number of times in only one m)
func (c *Column) SetPrimary(m *Migration) *Column {
m.Primary = append(m.Primary, c)
return c
}
-// AddColumnsToUnique adds the columns to Unique Struct
+//AddColumnsToUnique adds the columns to Unique Struct
func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique {
unique.Columns = append(unique.Columns, columns...)
@@ -225,7 +225,7 @@ func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique {
return unique
}
-// AddColumns adds columns to m struct
+//AddColumns adds columns to m struct
func (m *Migration) AddColumns(columns ...*Column) *Migration {
m.Columns = append(m.Columns, columns...)
@@ -233,38 +233,38 @@ func (m *Migration) AddColumns(columns ...*Column) *Migration {
return m
}
-// AddPrimary adds the column to primary in m struct
+//AddPrimary adds the column to primary in m struct
func (m *Migration) AddPrimary(primary *Column) *Migration {
m.Primary = append(m.Primary, primary)
return m
}
-// AddUnique adds the column to unique in m struct
+//AddUnique adds the column to unique in m struct
func (m *Migration) AddUnique(unique *Unique) *Migration {
m.Uniques = append(m.Uniques, unique)
return m
}
-// AddForeign adds the column to foreign in m struct
+//AddForeign adds the column to foreign in m struct
func (m *Migration) AddForeign(foreign *Foreign) *Migration {
m.Foreigns = append(m.Foreigns, foreign)
return m
}
-// AddIndex adds the column to index in m struct
+//AddIndex adds the column to index in m struct
func (m *Migration) AddIndex(index *Index) *Migration {
m.Indexes = append(m.Indexes, index)
return m
}
-// RenameColumn allows renaming of columns
+//RenameColumn allows renaming of columns
func (m *Migration) RenameColumn(from, to string) *RenameColumn {
rename := &RenameColumn{OldName: from, NewName: to}
m.Renames = append(m.Renames, rename)
return rename
}
-// GetSQL returns the generated sql depending on ModifyType
+//GetSQL returns the generated sql depending on ModifyType
func (m *Migration) GetSQL() (sql string) {
sql = ""
switch m.ModifyType {
diff --git a/adapter/migration/doc.go b/migration/doc.go
similarity index 100%
rename from adapter/migration/doc.go
rename to migration/doc.go
diff --git a/client/orm/migration/migration.go b/migration/migration.go
similarity index 99%
rename from client/orm/migration/migration.go
rename to migration/migration.go
index aeea12c6..5ddfd972 100644
--- a/client/orm/migration/migration.go
+++ b/migration/migration.go
@@ -33,8 +33,8 @@ import (
"strings"
"time"
- "github.com/astaxie/beego/client/orm"
- "github.com/astaxie/beego/core/logs"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/orm"
)
// const the data format for the bee generate migration datatype
diff --git a/server/web/mime.go b/mime.go
similarity index 99%
rename from server/web/mime.go
rename to mime.go
index 9393e9c7..ca2878ab 100644
--- a/server/web/mime.go
+++ b/mime.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
var mimemaps = map[string]string{
".3dm": "x-world/x-3dmf",
diff --git a/server/web/namespace.go b/namespace.go
similarity index 98%
rename from server/web/namespace.go
rename to namespace.go
index 58afb6c7..4952c9d5 100644
--- a/server/web/namespace.go
+++ b/namespace.go
@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"net/http"
"strings"
- beecontext "github.com/astaxie/beego/server/web/context"
+ beecontext "github.com/astaxie/beego/context"
)
type namespaceCond func(*beecontext.Context) bool
@@ -91,7 +91,7 @@ func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
a = FinishRouter
}
for _, f := range filter {
- n.handlers.InsertFilter("*", a, f, WithReturnOnOutput(true))
+ n.handlers.InsertFilter("*", a, f)
}
return n
}
diff --git a/server/web/namespace_test.go b/namespace_test.go
similarity index 98%
rename from server/web/namespace_test.go
rename to namespace_test.go
index a6f87bba..b3f20dff 100644
--- a/server/web/namespace_test.go
+++ b/namespace_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"net/http"
@@ -20,7 +20,7 @@ import (
"strconv"
"testing"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego/context"
)
func TestNamespaceGet(t *testing.T) {
diff --git a/client/orm/README.md b/orm/README.md
similarity index 100%
rename from client/orm/README.md
rename to orm/README.md
diff --git a/client/orm/cmd.go b/orm/cmd.go
similarity index 85%
rename from client/orm/cmd.go
rename to orm/cmd.go
index b0661971..0ff4dc40 100644
--- a/client/orm/cmd.go
+++ b/orm/cmd.go
@@ -46,7 +46,7 @@ func printHelp(errs ...string) {
os.Exit(2)
}
-// RunCommand listens for orm command and runs if command arguments have been passed.
+// RunCommand listen for orm command and then run it if command arguments passed.
func RunCommand() {
if len(os.Args) < 2 || os.Args[1] != "orm" {
return
@@ -83,7 +83,7 @@ type commandSyncDb struct {
rtOnError bool
}
-// Parse the orm command line arguments.
+// parse orm command line arguments.
func (d *commandSyncDb) Parse(args []string) {
var name string
@@ -96,20 +96,16 @@ func (d *commandSyncDb) Parse(args []string) {
d.al = getDbAlias(name)
}
-// Run orm line command.
+// run orm line command.
func (d *commandSyncDb) Run() error {
var drops []string
- var err error
if d.force {
- drops, err = modelCache.getDbDropSQL(d.al)
- if err != nil {
- return err
- }
+ drops = getDbDropSQL(d.al)
}
db := d.al.DB
- if d.force && len(drops) > 0 {
+ if d.force {
for i, mi := range modelCache.allOrdered() {
query := drops[i]
if !d.noInfo {
@@ -128,10 +124,7 @@ func (d *commandSyncDb) Run() error {
}
}
- createQueries, indexes, err := modelCache.getDbCreateSQL(d.al)
- if err != nil {
- return err
- }
+ sqls, indexes := getDbCreateSQL(d.al)
tables, err := d.al.DbBaser.GetTables(db)
if err != nil {
@@ -142,12 +135,6 @@ func (d *commandSyncDb) Run() error {
}
for i, mi := range modelCache.allOrdered() {
-
- if !isApplicableTableForDB(mi.addrField, d.al.Name) {
- fmt.Printf("table `%s` is not applicable to database '%s'\n", mi.table, d.al.Name)
- continue
- }
-
if tables[mi.table] {
if !d.noInfo {
fmt.Printf("table `%s` already exists, skip\n", mi.table)
@@ -214,7 +201,7 @@ func (d *commandSyncDb) Run() error {
fmt.Printf("create table `%s` \n", mi.table)
}
- queries := []string{createQueries[i]}
+ queries := []string{sqls[i]}
for _, idx := range indexes[mi.table] {
queries = append(queries, idx.SQL)
}
@@ -245,7 +232,7 @@ type commandSQLAll struct {
al *alias
}
-// Parse orm command line arguments.
+// parse orm command line arguments.
func (d *commandSQLAll) Parse(args []string) {
var name string
@@ -256,15 +243,12 @@ func (d *commandSQLAll) Parse(args []string) {
d.al = getDbAlias(name)
}
-// Run orm line command.
+// run orm line command.
func (d *commandSQLAll) Run() error {
- createQueries, indexes, err := modelCache.getDbCreateSQL(d.al)
- if err != nil {
- return err
- }
+ sqls, indexes := getDbCreateSQL(d.al)
var all []string
for i, mi := range modelCache.allOrdered() {
- queries := []string{createQueries[i]}
+ queries := []string{sqls[i]}
for _, idx := range indexes[mi.table] {
queries = append(queries, idx.SQL)
}
@@ -282,9 +266,9 @@ func init() {
}
// RunSyncdb run syncdb command line.
-// name: Table's alias name (default is "default")
-// force: Run the next sql command even if the current gave an error
-// verbose: Print all information, useful for debugging
+// name means table's alias name. default is "default".
+// force means run next sql if the current is error.
+// verbose means show all info when running command or not.
func RunSyncdb(name string, force bool, verbose bool) error {
BootStrap()
diff --git a/orm/cmd_utils.go b/orm/cmd_utils.go
new file mode 100644
index 00000000..61f17346
--- /dev/null
+++ b/orm/cmd_utils.go
@@ -0,0 +1,320 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "fmt"
+ "os"
+ "strings"
+)
+
+type dbIndex struct {
+ Table string
+ Name string
+ SQL string
+}
+
+// create database drop sql.
+func getDbDropSQL(al *alias) (sqls []string) {
+ if len(modelCache.cache) == 0 {
+ fmt.Println("no Model found, need register your model")
+ os.Exit(2)
+ }
+
+ Q := al.DbBaser.TableQuote()
+
+ for _, mi := range modelCache.allOrdered() {
+ sqls = append(sqls, fmt.Sprintf(`DROP TABLE IF EXISTS %s%s%s`, Q, mi.table, Q))
+ }
+ return sqls
+}
+
+// get database column type string.
+func getColumnTyp(al *alias, fi *fieldInfo) (col string) {
+ T := al.DbBaser.DbTypes()
+ fieldType := fi.fieldType
+ fieldSize := fi.size
+
+checkColumn:
+ switch fieldType {
+ case TypeBooleanField:
+ col = T["bool"]
+ case TypeVarCharField:
+ if al.Driver == DRPostgres && fi.toText {
+ col = T["string-text"]
+ } else {
+ col = fmt.Sprintf(T["string"], fieldSize)
+ }
+ case TypeCharField:
+ col = fmt.Sprintf(T["string-char"], fieldSize)
+ case TypeTextField:
+ col = T["string-text"]
+ case TypeTimeField:
+ col = T["time.Time-clock"]
+ case TypeDateField:
+ col = T["time.Time-date"]
+ case TypeDateTimeField:
+ col = T["time.Time"]
+ case TypeBitField:
+ col = T["int8"]
+ case TypeSmallIntegerField:
+ col = T["int16"]
+ case TypeIntegerField:
+ col = T["int32"]
+ case TypeBigIntegerField:
+ if al.Driver == DRSqlite {
+ fieldType = TypeIntegerField
+ goto checkColumn
+ }
+ col = T["int64"]
+ case TypePositiveBitField:
+ col = T["uint8"]
+ case TypePositiveSmallIntegerField:
+ col = T["uint16"]
+ case TypePositiveIntegerField:
+ col = T["uint32"]
+ case TypePositiveBigIntegerField:
+ col = T["uint64"]
+ case TypeFloatField:
+ col = T["float64"]
+ case TypeDecimalField:
+ s := T["float64-decimal"]
+ if !strings.Contains(s, "%d") {
+ col = s
+ } else {
+ col = fmt.Sprintf(s, fi.digits, fi.decimals)
+ }
+ case TypeJSONField:
+ if al.Driver != DRPostgres {
+ fieldType = TypeVarCharField
+ goto checkColumn
+ }
+ col = T["json"]
+ case TypeJsonbField:
+ if al.Driver != DRPostgres {
+ fieldType = TypeVarCharField
+ goto checkColumn
+ }
+ col = T["jsonb"]
+ case RelForeignKey, RelOneToOne:
+ fieldType = fi.relModelInfo.fields.pk.fieldType
+ fieldSize = fi.relModelInfo.fields.pk.size
+ goto checkColumn
+ }
+
+ return
+}
+
+// create alter sql string.
+func getColumnAddQuery(al *alias, fi *fieldInfo) string {
+ Q := al.DbBaser.TableQuote()
+ typ := getColumnTyp(al, fi)
+
+ if !fi.null {
+ typ += " " + "NOT NULL"
+ }
+
+ return fmt.Sprintf("ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s %s",
+ Q, fi.mi.table, Q,
+ Q, fi.column, Q,
+ typ, getColumnDefault(fi),
+ )
+}
+
+// create database creation string.
+func getDbCreateSQL(al *alias) (sqls []string, tableIndexes map[string][]dbIndex) {
+ if len(modelCache.cache) == 0 {
+ fmt.Println("no Model found, need register your model")
+ os.Exit(2)
+ }
+
+ Q := al.DbBaser.TableQuote()
+ T := al.DbBaser.DbTypes()
+ sep := fmt.Sprintf("%s, %s", Q, Q)
+
+ tableIndexes = make(map[string][]dbIndex)
+
+ for _, mi := range modelCache.allOrdered() {
+ sql := fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
+ sql += fmt.Sprintf("-- Table Structure for `%s`\n", mi.fullName)
+ sql += fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
+
+ sql += fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s%s%s (\n", Q, mi.table, Q)
+
+ columns := make([]string, 0, len(mi.fields.fieldsDB))
+
+ sqlIndexes := [][]string{}
+
+ for _, fi := range mi.fields.fieldsDB {
+
+ column := fmt.Sprintf(" %s%s%s ", Q, fi.column, Q)
+ col := getColumnTyp(al, fi)
+
+ if fi.auto {
+ switch al.Driver {
+ case DRSqlite, DRPostgres:
+ column += T["auto"]
+ default:
+ column += col + " " + T["auto"]
+ }
+ } else if fi.pk {
+ column += col + " " + T["pk"]
+ } else {
+ column += col
+
+ if !fi.null {
+ column += " " + "NOT NULL"
+ }
+
+ //if fi.initial.String() != "" {
+ // column += " DEFAULT " + fi.initial.String()
+ //}
+
+ // Append attribute DEFAULT
+ column += getColumnDefault(fi)
+
+ if fi.unique {
+ column += " " + "UNIQUE"
+ }
+
+ if fi.index {
+ sqlIndexes = append(sqlIndexes, []string{fi.column})
+ }
+ }
+
+ if strings.Contains(column, "%COL%") {
+ column = strings.Replace(column, "%COL%", fi.column, -1)
+ }
+
+ if fi.description != "" && al.Driver!=DRSqlite {
+ column += " " + fmt.Sprintf("COMMENT '%s'",fi.description)
+ }
+
+ columns = append(columns, column)
+ }
+
+ if mi.model != nil {
+ allnames := getTableUnique(mi.addrField)
+ if !mi.manual && len(mi.uniques) > 0 {
+ allnames = append(allnames, mi.uniques)
+ }
+ for _, names := range allnames {
+ cols := make([]string, 0, len(names))
+ for _, name := range names {
+ if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
+ cols = append(cols, fi.column)
+ } else {
+ panic(fmt.Errorf("cannot found column `%s` when parse UNIQUE in `%s.TableUnique`", name, mi.fullName))
+ }
+ }
+ column := fmt.Sprintf(" UNIQUE (%s%s%s)", Q, strings.Join(cols, sep), Q)
+ columns = append(columns, column)
+ }
+ }
+
+ sql += strings.Join(columns, ",\n")
+ sql += "\n)"
+
+ if al.Driver == DRMySQL {
+ var engine string
+ if mi.model != nil {
+ engine = getTableEngine(mi.addrField)
+ }
+ if engine == "" {
+ engine = al.Engine
+ }
+ sql += " ENGINE=" + engine
+ }
+
+ sql += ";"
+ sqls = append(sqls, sql)
+
+ if mi.model != nil {
+ for _, names := range getTableIndex(mi.addrField) {
+ cols := make([]string, 0, len(names))
+ for _, name := range names {
+ if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
+ cols = append(cols, fi.column)
+ } else {
+ panic(fmt.Errorf("cannot found column `%s` when parse INDEX in `%s.TableIndex`", name, mi.fullName))
+ }
+ }
+ sqlIndexes = append(sqlIndexes, cols)
+ }
+ }
+
+ for _, names := range sqlIndexes {
+ name := mi.table + "_" + strings.Join(names, "_")
+ cols := strings.Join(names, sep)
+ sql := fmt.Sprintf("CREATE INDEX %s%s%s ON %s%s%s (%s%s%s);", Q, name, Q, Q, mi.table, Q, Q, cols, Q)
+
+ index := dbIndex{}
+ index.Table = mi.table
+ index.Name = name
+ index.SQL = sql
+
+ tableIndexes[mi.table] = append(tableIndexes[mi.table], index)
+ }
+
+ }
+
+ return
+}
+
+// Get string value for the attribute "DEFAULT" for the CREATE, ALTER commands
+func getColumnDefault(fi *fieldInfo) string {
+ var (
+ v, t, d string
+ )
+
+ // Skip default attribute if field is in relations
+ if fi.rel || fi.reverse {
+ return v
+ }
+
+ t = " DEFAULT '%s' "
+
+ // These defaults will be useful if there no config value orm:"default" and NOT NULL is on
+ switch fi.fieldType {
+ case TypeTimeField, TypeDateField, TypeDateTimeField, TypeTextField:
+ return v
+
+ case TypeBitField, TypeSmallIntegerField, TypeIntegerField,
+ TypeBigIntegerField, TypePositiveBitField, TypePositiveSmallIntegerField,
+ TypePositiveIntegerField, TypePositiveBigIntegerField, TypeFloatField,
+ TypeDecimalField:
+ t = " DEFAULT %s "
+ d = "0"
+ case TypeBooleanField:
+ t = " DEFAULT %s "
+ d = "FALSE"
+ case TypeJSONField, TypeJsonbField:
+ d = "{}"
+ }
+
+ if fi.colDefault {
+ if !fi.initial.Exist() {
+ v = fmt.Sprintf(t, "")
+ } else {
+ v = fmt.Sprintf(t, fi.initial.String())
+ }
+ } else {
+ if !fi.null {
+ v = fmt.Sprintf(t, d)
+ }
+ }
+
+ return v
+}
diff --git a/client/orm/db.go b/orm/db.go
similarity index 94%
rename from client/orm/db.go
rename to orm/db.go
index b103d218..9a1827e8 100644
--- a/client/orm/db.go
+++ b/orm/db.go
@@ -21,8 +21,6 @@ import (
"reflect"
"strings"
"time"
-
- "github.com/astaxie/beego/client/orm/hints"
)
const (
@@ -38,11 +36,10 @@ var (
var (
operators = map[string]bool{
- "exact": true,
- "iexact": true,
- "strictexact": true,
- "contains": true,
- "icontains": true,
+ "exact": true,
+ "iexact": true,
+ "contains": true,
+ "icontains": true,
// "regex": true,
// "iregex": true,
"gt": true,
@@ -487,14 +484,7 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
if isMulti {
return res.RowsAffected()
}
-
- lastInsertId, err := res.LastInsertId()
- if err != nil {
- DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
- return lastInsertId, ErrLastInsertIdUnavailable
- } else {
- return lastInsertId, nil
- }
+ return res.LastInsertId()
}
return 0, err
}
@@ -595,14 +585,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
if isMulti {
return res.RowsAffected()
}
-
- lastInsertId, err := res.LastInsertId()
- if err != nil {
- DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
- return lastInsertId, ErrLastInsertIdUnavailable
- } else {
- return lastInsertId, nil
- }
+ return res.LastInsertId()
}
return 0, err
}
@@ -755,10 +738,8 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
}
tables := newDbTables(mi, d.ins)
- var specifyIndexes string
if qs != nil {
tables.parseRelated(qs.related, qs.relDepth)
- specifyIndexes = tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
}
where, args := tables.getCondSQL(cond, false, tz)
@@ -809,12 +790,9 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
sets := strings.Join(cols, ", ") + " "
if d.ins.SupportUpdateJoin() {
- query = fmt.Sprintf("UPDATE %s%s%s T0 %s%sSET %s%s", Q, mi.table, Q, specifyIndexes, join, sets, where)
+ query = fmt.Sprintf("UPDATE %s%s%s T0 %sSET %s%s", Q, mi.table, Q, join, sets, where)
} else {
- supQuery := fmt.Sprintf("SELECT T0.%s%s%s FROM %s%s%s T0 %s%s%s",
- Q, mi.fields.pk.column, Q,
- Q, mi.table, Q,
- specifyIndexes, join, where)
+ supQuery := fmt.Sprintf("SELECT T0.%s%s%s FROM %s%s%s T0 %s%s", Q, mi.fields.pk.column, Q, Q, mi.table, Q, join, where)
query = fmt.Sprintf("UPDATE %s%s%s SET %sWHERE %s%s%s IN ( %s )", Q, mi.table, Q, sets, Q, mi.fields.pk.column, Q, supQuery)
}
@@ -865,10 +843,8 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
tables := newDbTables(mi, d.ins)
tables.skipEnd = true
- var specifyIndexes string
if qs != nil {
tables.parseRelated(qs.related, qs.relDepth)
- specifyIndexes = tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
}
if cond == nil || cond.IsEmpty() {
@@ -881,7 +857,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
join := tables.getJoinSQL()
cols := fmt.Sprintf("T0.%s%s%s", Q, mi.fields.pk.column, Q)
- query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s%s", cols, Q, mi.table, Q, specifyIndexes, join, where)
+ query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s", cols, Q, mi.table, Q, join, where)
d.ins.ReplaceMarks(&query)
@@ -1026,7 +1002,6 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
orderBy := tables.getOrderSQL(qs.orders)
limit := tables.getLimitSQL(mi, offset, rlimit)
join := tables.getJoinSQL()
- specifyIndexes := tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
for _, tbl := range tables.tables {
if tbl.sel {
@@ -1040,11 +1015,9 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
if qs.distinct {
sqlSelect += " DISTINCT"
}
- query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s%s",
- sqlSelect, sels, Q, mi.table, Q,
- specifyIndexes, join, where, groupBy, orderBy, limit)
+ query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, groupBy, orderBy, limit)
- if qs.forUpdate {
+ if qs.forupdate {
query += " FOR UPDATE"
}
@@ -1180,13 +1153,10 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition
groupBy := tables.getGroupSQL(qs.groups)
tables.getOrderSQL(qs.orders)
join := tables.getJoinSQL()
- specifyIndexes := tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
Q := d.ins.TableQuote()
- query := fmt.Sprintf("SELECT COUNT(*) FROM %s%s%s T0 %s%s%s%s",
- Q, mi.table, Q,
- specifyIndexes, join, where, groupBy)
+ query := fmt.Sprintf("SELECT COUNT(*) FROM %s%s%s T0 %s%s%s", Q, mi.table, Q, join, where, groupBy)
if groupBy != "" {
query = fmt.Sprintf("SELECT COUNT(*) FROM (%s) AS T", query)
@@ -1356,14 +1326,7 @@ setValue:
t time.Time
err error
)
-
- if fi.timePrecision != nil && len(s) >= (20+*fi.timePrecision) {
- layout := formatDateTime + "."
- for i := 0; i < *fi.timePrecision; i++ {
- layout += "0"
- }
- t, err = time.ParseInLocation(layout, s[:20+*fi.timePrecision], tz)
- } else if len(s) >= 19 {
+ if len(s) >= 19 {
s = s[:19]
t, err = time.ParseInLocation(formatDateTime, s, tz)
} else if len(s) >= 10 {
@@ -1717,7 +1680,6 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
orderBy := tables.getOrderSQL(qs.orders)
limit := tables.getLimitSQL(mi, qs.offset, qs.limit)
join := tables.getJoinSQL()
- specifyIndexes := tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
sels := strings.Join(cols, ", ")
@@ -1725,10 +1687,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
if qs.distinct {
sqlSelect += " DISTINCT"
}
- query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s%s",
- sqlSelect, sels,
- Q, mi.table, Q,
- specifyIndexes, join, where, groupBy, orderBy, limit)
+ query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, groupBy, orderBy, limit)
d.ins.ReplaceMarks(&query)
@@ -1822,6 +1781,10 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
return cnt, nil
}
+func (d *dbBase) RowsTo(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, string, string, *time.Location) (int64, error) {
+ return 0, nil
+}
+
// flag of update joined record.
func (d *dbBase) SupportUpdateJoin() bool {
return true
@@ -1937,29 +1900,3 @@ func (d *dbBase) ShowColumnsQuery(table string) string {
func (d *dbBase) IndexExists(dbQuerier, string, string) bool {
panic(ErrNotImplement)
}
-
-// GenerateSpecifyIndex return a specifying index clause
-func (d *dbBase) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
- var s []string
- Q := d.TableQuote()
- for _, index := range indexes {
- tmp := fmt.Sprintf(`%s%s%s`, Q, index, Q)
- s = append(s, tmp)
- }
-
- var useWay string
-
- switch useIndex {
- case hints.KeyUseIndex:
- useWay = `USE`
- case hints.KeyForceIndex:
- useWay = `FORCE`
- case hints.KeyIgnoreIndex:
- useWay = `IGNORE`
- default:
- DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
- return ``
- }
-
- return fmt.Sprintf(` %s INDEX(%s) `, useWay, strings.Join(s, `,`))
-}
diff --git a/client/orm/db_alias.go b/orm/db_alias.go
similarity index 62%
rename from client/orm/db_alias.go
rename to orm/db_alias.go
index 29e0904c..cf6a5935 100644
--- a/client/orm/db_alias.go
+++ b/orm/db_alias.go
@@ -18,10 +18,10 @@ import (
"context"
"database/sql"
"fmt"
+ lru "github.com/hashicorp/golang-lru"
+ "reflect"
"sync"
"time"
-
- lru "github.com/hashicorp/golang-lru"
)
// DriverType database driver constant int.
@@ -63,7 +63,7 @@ var (
"tidb": DRTiDB,
"oracle": DROracle,
"oci8": DROracle, // github.com/mattn/go-oci8
- "ora": DROracle, // https://github.com/rana/ora
+ "ora": DROracle, //https://github.com/rana/ora
}
dbBasers = map[DriverType]dbBaser{
DRMySQL: newdbBaseMysql(),
@@ -107,14 +107,10 @@ func (ac *_dbCache) getDefault() (al *alias) {
type DB struct {
*sync.RWMutex
- DB *sql.DB
- stmtDecorators *lru.Cache
- stmtDecoratorsLimit int
+ DB *sql.DB
+ stmtDecorators *lru.Cache
}
-var _ dbQuerier = new(DB)
-var _ txer = new(DB)
-
func (d *DB) Begin() (*sql.Tx, error) {
return d.DB.Begin()
}
@@ -123,7 +119,7 @@ func (d *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
return d.DB.BeginTx(ctx, opts)
}
-// su must call release to release *sql.Stmt after using
+//su must call release to release *sql.Stmt after using
func (d *DB) getStmtDecorator(query string) (*stmtDecorator, error) {
d.RLock()
c, ok := d.stmtDecorators.Get(query)
@@ -164,14 +160,16 @@ func (d *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error
}
func (d *DB) Exec(query string, args ...interface{}) (sql.Result, error) {
- return d.ExecContext(context.Background(), query, args...)
+ sd, err := d.getStmtDecorator(query)
+ if err != nil {
+ return nil, err
+ }
+ stmt := sd.getStmt()
+ defer sd.release()
+ return stmt.Exec(args...)
}
func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
- if d.stmtDecorators == nil {
- return d.DB.ExecContext(ctx, query, args...)
- }
-
sd, err := d.getStmtDecorator(query)
if err != nil {
return nil, err
@@ -182,14 +180,16 @@ func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{})
}
func (d *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
- return d.QueryContext(context.Background(), query, args...)
+ sd, err := d.getStmtDecorator(query)
+ if err != nil {
+ return nil, err
+ }
+ stmt := sd.getStmt()
+ defer sd.release()
+ return stmt.Query(args...)
}
func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
- if d.stmtDecorators == nil {
- return d.DB.QueryContext(ctx, query, args...)
- }
-
sd, err := d.getStmtDecorator(query)
if err != nil {
return nil, err
@@ -200,86 +200,37 @@ func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}
}
func (d *DB) QueryRow(query string, args ...interface{}) *sql.Row {
- return d.QueryRowContext(context.Background(), query, args...)
-}
-
-func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
- if d.stmtDecorators == nil {
- return d.DB.QueryRowContext(ctx, query, args...)
- }
-
sd, err := d.getStmtDecorator(query)
if err != nil {
panic(err)
}
stmt := sd.getStmt()
defer sd.release()
- return stmt.QueryRowContext(ctx, args...)
+ return stmt.QueryRow(args...)
+
}
-type TxDB struct {
- tx *sql.Tx
-}
-
-var _ dbQuerier = new(TxDB)
-var _ txEnder = new(TxDB)
-
-func (t *TxDB) Commit() error {
- return t.tx.Commit()
-}
-
-func (t *TxDB) Rollback() error {
- return t.tx.Rollback()
-}
-
-var _ dbQuerier = new(TxDB)
-var _ txEnder = new(TxDB)
-
-func (t *TxDB) Prepare(query string) (*sql.Stmt, error) {
- return t.PrepareContext(context.Background(), query)
-}
-
-func (t *TxDB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
- return t.tx.PrepareContext(ctx, query)
-}
-
-func (t *TxDB) Exec(query string, args ...interface{}) (sql.Result, error) {
- return t.ExecContext(context.Background(), query, args...)
-}
-
-func (t *TxDB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
- return t.tx.ExecContext(ctx, query, args...)
-}
-
-func (t *TxDB) Query(query string, args ...interface{}) (*sql.Rows, error) {
- return t.QueryContext(context.Background(), query, args...)
-}
-
-func (t *TxDB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
- return t.tx.QueryContext(ctx, query, args...)
-}
-
-func (t *TxDB) QueryRow(query string, args ...interface{}) *sql.Row {
- return t.QueryRowContext(context.Background(), query, args...)
-}
-
-func (t *TxDB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
- return t.tx.QueryRowContext(ctx, query, args...)
+func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
+ sd, err := d.getStmtDecorator(query)
+ if err != nil {
+ panic(err)
+ }
+ stmt := sd.getStmt()
+ defer sd.release()
+ return stmt.QueryRowContext(ctx, args)
}
type alias struct {
- Name string
- Driver DriverType
- DriverName string
- DataSource string
- MaxIdleConns int
- MaxOpenConns int
- ConnMaxLifetime time.Duration
- StmtCacheSize int
- DB *DB
- DbBaser dbBaser
- TZ *time.Location
- Engine string
+ Name string
+ Driver DriverType
+ DriverName string
+ DataSource string
+ MaxIdleConns int
+ MaxOpenConns int
+ DB *DB
+ DbBaser dbBaser
+ TZ *time.Location
+ Engine string
}
func detectTZ(al *alias) {
@@ -338,53 +289,15 @@ func detectTZ(al *alias) {
}
}
-func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) {
- existErr := fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName)
- if _, ok := dataBaseCache.get(aliasName); ok {
- return nil, existErr
- }
-
- al, err := newAliasWithDb(aliasName, driverName, db, params...)
- if err != nil {
- return nil, err
- }
-
- if !dataBaseCache.add(aliasName, al) {
- return nil, existErr
- }
-
- return al, nil
-}
-
-func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) {
-
- al := &alias{}
- al.DB = &DB{
- RWMutex: new(sync.RWMutex),
- DB: db,
- }
-
- for _, p := range params {
- p(al)
- }
-
- var stmtCache *lru.Cache
- var stmtCacheSize int
-
- if al.StmtCacheSize > 0 {
- _stmtCache, errC := newStmtDecoratorLruWithEvict(al.StmtCacheSize)
- if errC != nil {
- return nil, errC
- } else {
- stmtCache = _stmtCache
- stmtCacheSize = al.StmtCacheSize
- }
- }
-
+func addAliasWthDB(aliasName, driverName string, db *sql.DB) (*alias, error) {
+ al := new(alias)
al.Name = aliasName
al.DriverName = driverName
- al.DB.stmtDecorators = stmtCache
- al.DB.stmtDecoratorsLimit = stmtCacheSize
+ al.DB = &DB{
+ RWMutex: new(sync.RWMutex),
+ DB: db,
+ stmtDecorators: newStmtDecoratorLruWithEvict(),
+ }
if dr, ok := drivers[driverName]; ok {
al.DbBaser = dbBasers[dr]
@@ -398,50 +311,21 @@ func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...DBOption
return nil, fmt.Errorf("register db Ping `%s`, %s", aliasName, err.Error())
}
- detectTZ(al)
+ if !dataBaseCache.add(aliasName, al) {
+ return nil, fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName)
+ }
return al, nil
}
-// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
-// Deprecated you should not use this, we will remove it in the future
-func SetMaxIdleConns(aliasName string, maxIdleConns int) {
- al := getDbAlias(aliasName)
- al.SetMaxIdleConns(maxIdleConns)
-}
-
-// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
-// Deprecated you should not use this, we will remove it in the future
-func SetMaxOpenConns(aliasName string, maxOpenConns int) {
- al := getDbAlias(aliasName)
- al.SetMaxIdleConns(maxOpenConns)
-}
-
-// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
-func (al *alias) SetMaxIdleConns(maxIdleConns int) {
- al.MaxIdleConns = maxIdleConns
- al.DB.DB.SetMaxIdleConns(maxIdleConns)
-}
-
-// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
-func (al *alias) SetMaxOpenConns(maxOpenConns int) {
- al.MaxOpenConns = maxOpenConns
- al.DB.DB.SetMaxOpenConns(maxOpenConns)
-}
-
-func (al *alias) SetConnMaxLifetime(lifeTime time.Duration) {
- al.ConnMaxLifetime = lifeTime
- al.DB.DB.SetConnMaxLifetime(lifeTime)
-}
-
// AddAliasWthDB add a aliasName for the drivename
-func AddAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) error {
- _, err := addAliasWthDB(aliasName, driverName, db, params...)
+func AddAliasWthDB(aliasName, driverName string, db *sql.DB) error {
+ _, err := addAliasWthDB(aliasName, driverName, db)
return err
}
// RegisterDataBase Setting the database connect params. Use the database driver self dataSource args.
-func RegisterDataBase(aliasName, driverName, dataSource string, params ...DBOption) error {
+func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error {
var (
err error
db *sql.DB
@@ -454,13 +338,24 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...DBOpti
goto end
}
- al, err = addAliasWthDB(aliasName, driverName, db, params...)
+ al, err = addAliasWthDB(aliasName, driverName, db)
if err != nil {
goto end
}
al.DataSource = dataSource
+ detectTZ(al)
+
+ for i, v := range params {
+ switch i {
+ case 0:
+ SetMaxIdleConns(al.Name, v)
+ case 1:
+ SetMaxOpenConns(al.Name, v)
+ }
+ }
+
end:
if err != nil {
if db != nil {
@@ -494,6 +389,24 @@ func SetDataBaseTZ(aliasName string, tz *time.Location) error {
return nil
}
+// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
+func SetMaxIdleConns(aliasName string, maxIdleConns int) {
+ al := getDbAlias(aliasName)
+ al.MaxIdleConns = maxIdleConns
+ al.DB.DB.SetMaxIdleConns(maxIdleConns)
+}
+
+// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
+func SetMaxOpenConns(aliasName string, maxOpenConns int) {
+ al := getDbAlias(aliasName)
+ al.MaxOpenConns = maxOpenConns
+ al.DB.DB.SetMaxOpenConns(maxOpenConns)
+ // for tip go 1.2
+ if fun := reflect.ValueOf(al.DB).MethodByName("SetMaxOpenConns"); fun.IsValid() {
+ fun.Call([]reflect.Value{reflect.ValueOf(maxOpenConns)})
+ }
+}
+
// GetDB Get *sql.DB from registered database by db alias name.
// Use "default" as alias name if you not set.
func GetDB(aliasNames ...string) (*sql.DB, error) {
@@ -511,7 +424,8 @@ func GetDB(aliasNames ...string) (*sql.DB, error) {
}
type stmtDecorator struct {
- wg sync.WaitGroup
+ wg sync.WaitGroup
+ lastUse int64
stmt *sql.Stmt
}
@@ -519,19 +433,16 @@ func (s *stmtDecorator) getStmt() *sql.Stmt {
return s.stmt
}
-// acquire will add one
-// since this method will be used inside read lock scope,
-// so we can not do more things here
-// we should think about refactor this
func (s *stmtDecorator) acquire() {
s.wg.Add(1)
+ s.lastUse = time.Now().Unix()
}
func (s *stmtDecorator) release() {
s.wg.Done()
}
-// garbage recycle for stmt
+//garbage recycle for stmt
func (s *stmtDecorator) destroy() {
go func() {
s.wg.Wait()
@@ -542,45 +453,13 @@ func (s *stmtDecorator) destroy() {
func newStmtDecorator(sqlStmt *sql.Stmt) *stmtDecorator {
return &stmtDecorator{
stmt: sqlStmt,
+ lastUse: time.Now().Unix(),
}
}
-func newStmtDecoratorLruWithEvict(cacheSize int) (*lru.Cache, error) {
- cache, err := lru.NewWithEvict(cacheSize, func(key interface{}, value interface{}) {
+func newStmtDecoratorLruWithEvict() *lru.Cache {
+ cache, _ := lru.NewWithEvict(1000, func(key interface{}, value interface{}) {
value.(*stmtDecorator).destroy()
})
- if err != nil {
- return nil, err
- }
- return cache, nil
-}
-
-type DBOption func(al *alias)
-
-// MaxIdleConnections return a hint about MaxIdleConnections
-func MaxIdleConnections(maxIdleConn int) DBOption {
- return func(al *alias) {
- al.SetMaxIdleConns(maxIdleConn)
- }
-}
-
-// MaxOpenConnections return a hint about MaxOpenConnections
-func MaxOpenConnections(maxOpenConn int) DBOption {
- return func(al *alias) {
- al.SetMaxOpenConns(maxOpenConn)
- }
-}
-
-// ConnMaxLifetime return a hint about ConnMaxLifetime
-func ConnMaxLifetime(v time.Duration) DBOption {
- return func(al *alias) {
- al.SetConnMaxLifetime(v)
- }
-}
-
-// MaxStmtCacheSize return a hint about MaxStmtCacheSize
-func MaxStmtCacheSize(v int) DBOption {
- return func(al *alias) {
- al.StmtCacheSize = v
- }
+ return cache
}
diff --git a/client/orm/db_mysql.go b/orm/db_mysql.go
similarity index 79%
rename from client/orm/db_mysql.go
rename to orm/db_mysql.go
index f674ab2b..6e99058e 100644
--- a/client/orm/db_mysql.go
+++ b/orm/db_mysql.go
@@ -22,11 +22,10 @@ import (
// mysql operators.
var mysqlOperators = map[string]string{
- "exact": "= ?",
- "iexact": "LIKE ?",
- "strictexact": "= BINARY ?",
- "contains": "LIKE BINARY ?",
- "icontains": "LIKE ?",
+ "exact": "= ?",
+ "iexact": "LIKE ?",
+ "contains": "LIKE BINARY ?",
+ "icontains": "LIKE ?",
// "regex": "REGEXP BINARY ?",
// "iregex": "REGEXP ?",
"gt": "> ?",
@@ -43,25 +42,24 @@ var mysqlOperators = map[string]string{
// mysql column field types.
var mysqlTypes = map[string]string{
- "auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY",
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "varchar(%d)",
- "string-char": "char(%d)",
- "string-text": "longtext",
- "time.Time-date": "date",
- "time.Time": "datetime",
- "int8": "tinyint",
- "int16": "smallint",
- "int32": "integer",
- "int64": "bigint",
- "uint8": "tinyint unsigned",
- "uint16": "smallint unsigned",
- "uint32": "integer unsigned",
- "uint64": "bigint unsigned",
- "float64": "double precision",
- "float64-decimal": "numeric(%d, %d)",
- "time.Time-precision": "datetime(%d)",
+ "auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "varchar(%d)",
+ "string-char": "char(%d)",
+ "string-text": "longtext",
+ "time.Time-date": "date",
+ "time.Time": "datetime",
+ "int8": "tinyint",
+ "int16": "smallint",
+ "int32": "integer",
+ "int64": "bigint",
+ "uint8": "tinyint unsigned",
+ "uint16": "smallint unsigned",
+ "uint32": "integer unsigned",
+ "uint64": "bigint unsigned",
+ "float64": "double precision",
+ "float64-decimal": "numeric(%d, %d)",
}
// mysql dbBaser implementation.
@@ -166,14 +164,7 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
if isMulti {
return res.RowsAffected()
}
-
- lastInsertId, err := res.LastInsertId()
- if err != nil {
- DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
- return lastInsertId, ErrLastInsertIdUnavailable
- } else {
- return lastInsertId, nil
- }
+ return res.LastInsertId()
}
return 0, err
}
diff --git a/client/orm/db_oracle.go b/orm/db_oracle.go
similarity index 67%
rename from client/orm/db_oracle.go
rename to orm/db_oracle.go
index cb0d5052..5d121f83 100644
--- a/client/orm/db_oracle.go
+++ b/orm/db_oracle.go
@@ -17,8 +17,6 @@ package orm
import (
"fmt"
"strings"
-
- "github.com/astaxie/beego/client/orm/hints"
)
// oracle operators.
@@ -33,24 +31,23 @@ var oracleOperators = map[string]string{
// oracle column field types.
var oracleTypes = map[string]string{
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "VARCHAR2(%d)",
- "string-char": "CHAR(%d)",
- "string-text": "VARCHAR2(%d)",
- "time.Time-date": "DATE",
- "time.Time": "TIMESTAMP",
- "int8": "INTEGER",
- "int16": "INTEGER",
- "int32": "INTEGER",
- "int64": "INTEGER",
- "uint8": "INTEGER",
- "uint16": "INTEGER",
- "uint32": "INTEGER",
- "uint64": "INTEGER",
- "float64": "NUMBER",
- "float64-decimal": "NUMBER(%d, %d)",
- "time.Time-precision": "TIMESTAMP(%d)",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "VARCHAR2(%d)",
+ "string-char": "CHAR(%d)",
+ "string-text": "VARCHAR2(%d)",
+ "time.Time-date": "DATE",
+ "time.Time": "TIMESTAMP",
+ "int8": "INTEGER",
+ "int16": "INTEGER",
+ "int32": "INTEGER",
+ "int64": "INTEGER",
+ "uint8": "INTEGER",
+ "uint16": "INTEGER",
+ "uint32": "INTEGER",
+ "uint64": "INTEGER",
+ "float64": "NUMBER",
+ "float64-decimal": "NUMBER(%d, %d)",
}
// oracle dbBaser
@@ -99,29 +96,6 @@ func (d *dbBaseOracle) IndexExists(db dbQuerier, table string, name string) bool
return cnt > 0
}
-func (d *dbBaseOracle) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
- var s []string
- Q := d.TableQuote()
- for _, index := range indexes {
- tmp := fmt.Sprintf(`%s%s%s`, Q, index, Q)
- s = append(s, tmp)
- }
-
- var hint string
-
- switch useIndex {
- case hints.KeyUseIndex, hints.KeyForceIndex:
- hint = `INDEX`
- case hints.KeyIgnoreIndex:
- hint = `NO_INDEX`
- default:
- DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
- return ``
- }
-
- return fmt.Sprintf(` /*+ %s(%s %s)*/ `, hint, tableName, strings.Join(s, `,`))
-}
-
// execute insert sql with given struct and given values.
// insert the given values, not the field values in struct.
func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) {
@@ -152,14 +126,7 @@ func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, nam
if isMulti {
return res.RowsAffected()
}
-
- lastInsertId, err := res.LastInsertId()
- if err != nil {
- DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
- return lastInsertId, ErrLastInsertIdUnavailable
- } else {
- return lastInsertId, nil
- }
+ return res.LastInsertId()
}
return 0, err
}
diff --git a/client/orm/db_postgres.go b/orm/db_postgres.go
similarity index 78%
rename from client/orm/db_postgres.go
rename to orm/db_postgres.go
index 12431d6e..c488fb38 100644
--- a/client/orm/db_postgres.go
+++ b/orm/db_postgres.go
@@ -39,27 +39,26 @@ var postgresOperators = map[string]string{
// postgresql column field types.
var postgresTypes = map[string]string{
- "auto": "serial NOT NULL PRIMARY KEY",
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "varchar(%d)",
- "string-char": "char(%d)",
- "string-text": "text",
- "time.Time-date": "date",
- "time.Time": "timestamp with time zone",
- "int8": `smallint CHECK("%COL%" >= -127 AND "%COL%" <= 128)`,
- "int16": "smallint",
- "int32": "integer",
- "int64": "bigint",
- "uint8": `smallint CHECK("%COL%" >= 0 AND "%COL%" <= 255)`,
- "uint16": `integer CHECK("%COL%" >= 0)`,
- "uint32": `bigint CHECK("%COL%" >= 0)`,
- "uint64": `bigint CHECK("%COL%" >= 0)`,
- "float64": "double precision",
- "float64-decimal": "numeric(%d, %d)",
- "json": "json",
- "jsonb": "jsonb",
- "time.Time-precision": "timestamp(%d) with time zone",
+ "auto": "serial NOT NULL PRIMARY KEY",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "varchar(%d)",
+ "string-char": "char(%d)",
+ "string-text": "text",
+ "time.Time-date": "date",
+ "time.Time": "timestamp with time zone",
+ "int8": `smallint CHECK("%COL%" >= -127 AND "%COL%" <= 128)`,
+ "int16": "smallint",
+ "int32": "integer",
+ "int64": "bigint",
+ "uint8": `smallint CHECK("%COL%" >= 0 AND "%COL%" <= 255)`,
+ "uint16": `integer CHECK("%COL%" >= 0)`,
+ "uint32": `bigint CHECK("%COL%" >= 0)`,
+ "uint64": `bigint CHECK("%COL%" >= 0)`,
+ "float64": "double precision",
+ "float64-decimal": "numeric(%d, %d)",
+ "json": "json",
+ "jsonb": "jsonb",
}
// postgresql dbBaser.
@@ -182,12 +181,6 @@ func (d *dbBasePostgres) IndexExists(db dbQuerier, table string, name string) bo
return cnt > 0
}
-// GenerateSpecifyIndex return a specifying index clause
-func (d *dbBasePostgres) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
- DebugLog.Println("[WARN] Not support any specifying index action, so that action is ignored")
- return ``
-}
-
// create new postgresql dbBaser.
func newdbBasePostgres() dbBaser {
b := new(dbBasePostgres)
diff --git a/client/orm/db_sqlite.go b/orm/db_sqlite.go
similarity index 73%
rename from client/orm/db_sqlite.go
rename to orm/db_sqlite.go
index 961f2535..1d62ee34 100644
--- a/client/orm/db_sqlite.go
+++ b/orm/db_sqlite.go
@@ -18,10 +18,7 @@ import (
"database/sql"
"fmt"
"reflect"
- "strings"
"time"
-
- "github.com/astaxie/beego/client/orm/hints"
)
// sqlite operators.
@@ -44,25 +41,24 @@ var sqliteOperators = map[string]string{
// sqlite column types.
var sqliteTypes = map[string]string{
- "auto": "integer NOT NULL PRIMARY KEY AUTOINCREMENT",
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "varchar(%d)",
- "string-char": "character(%d)",
- "string-text": "text",
- "time.Time-date": "date",
- "time.Time": "datetime",
- "time.Time-precision": "datetime(%d)",
- "int8": "tinyint",
- "int16": "smallint",
- "int32": "integer",
- "int64": "bigint",
- "uint8": "tinyint unsigned",
- "uint16": "smallint unsigned",
- "uint32": "integer unsigned",
- "uint64": "bigint unsigned",
- "float64": "real",
- "float64-decimal": "decimal",
+ "auto": "integer NOT NULL PRIMARY KEY AUTOINCREMENT",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "varchar(%d)",
+ "string-char": "character(%d)",
+ "string-text": "text",
+ "time.Time-date": "date",
+ "time.Time": "datetime",
+ "int8": "tinyint",
+ "int16": "smallint",
+ "int32": "integer",
+ "int64": "bigint",
+ "uint8": "tinyint unsigned",
+ "uint16": "smallint unsigned",
+ "uint32": "integer unsigned",
+ "uint64": "bigint unsigned",
+ "float64": "real",
+ "float64-decimal": "decimal",
}
// sqlite dbBaser.
@@ -157,24 +153,6 @@ func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool
return false
}
-// GenerateSpecifyIndex return a specifying index clause
-func (d *dbBaseSqlite) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
- var s []string
- Q := d.TableQuote()
- for _, index := range indexes {
- tmp := fmt.Sprintf(`%s%s%s`, Q, index, Q)
- s = append(s, tmp)
- }
-
- switch useIndex {
- case hints.KeyUseIndex, hints.KeyForceIndex:
- return fmt.Sprintf(` INDEXED BY %s `, strings.Join(s, `,`))
- default:
- DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
- return ``
- }
-}
-
// create new sqlite dbBaser.
func newdbBaseSqlite() dbBaser {
b := new(dbBaseSqlite)
diff --git a/client/orm/db_tables.go b/orm/db_tables.go
similarity index 97%
rename from client/orm/db_tables.go
rename to orm/db_tables.go
index 5fd472d1..4b21a6fc 100644
--- a/client/orm/db_tables.go
+++ b/orm/db_tables.go
@@ -472,15 +472,6 @@ func (t *dbTables) getLimitSQL(mi *modelInfo, offset int64, limit int64) (limits
return
}
-// getIndexSql generate index sql.
-func (t *dbTables) getIndexSql(tableName string, useIndex int, indexes []string) (clause string) {
- if len(indexes) == 0 {
- return
- }
-
- return t.base.GenerateSpecifyIndex(tableName, useIndex, indexes)
-}
-
// crete new tables collection.
func newDbTables(mi *modelInfo, base dbBaser) *dbTables {
tables := &dbTables{}
diff --git a/client/orm/db_tidb.go b/orm/db_tidb.go
similarity index 100%
rename from client/orm/db_tidb.go
rename to orm/db_tidb.go
diff --git a/client/orm/db_utils.go b/orm/db_utils.go
similarity index 100%
rename from client/orm/db_utils.go
rename to orm/db_utils.go
diff --git a/orm/models.go b/orm/models.go
new file mode 100644
index 00000000..4776bcba
--- /dev/null
+++ b/orm/models.go
@@ -0,0 +1,99 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "sync"
+)
+
+const (
+ odCascade = "cascade"
+ odSetNULL = "set_null"
+ odSetDefault = "set_default"
+ odDoNothing = "do_nothing"
+ defaultStructTagName = "orm"
+ defaultStructTagDelim = ";"
+)
+
+var (
+ modelCache = &_modelCache{
+ cache: make(map[string]*modelInfo),
+ cacheByFullName: make(map[string]*modelInfo),
+ }
+)
+
+// model info collection
+type _modelCache struct {
+ sync.RWMutex // only used outsite for bootStrap
+ orders []string
+ cache map[string]*modelInfo
+ cacheByFullName map[string]*modelInfo
+ done bool
+}
+
+// get all model info
+func (mc *_modelCache) all() map[string]*modelInfo {
+ m := make(map[string]*modelInfo, len(mc.cache))
+ for k, v := range mc.cache {
+ m[k] = v
+ }
+ return m
+}
+
+// get ordered model info
+func (mc *_modelCache) allOrdered() []*modelInfo {
+ m := make([]*modelInfo, 0, len(mc.orders))
+ for _, table := range mc.orders {
+ m = append(m, mc.cache[table])
+ }
+ return m
+}
+
+// get model info by table name
+func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) {
+ mi, ok = mc.cache[table]
+ return
+}
+
+// get model info by full name
+func (mc *_modelCache) getByFullName(name string) (mi *modelInfo, ok bool) {
+ mi, ok = mc.cacheByFullName[name]
+ return
+}
+
+// set model info to collection
+func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
+ mii := mc.cache[table]
+ mc.cache[table] = mi
+ mc.cacheByFullName[mi.fullName] = mi
+ if mii == nil {
+ mc.orders = append(mc.orders, table)
+ }
+ return mii
+}
+
+// clean all model info.
+func (mc *_modelCache) clean() {
+ mc.orders = make([]string, 0)
+ mc.cache = make(map[string]*modelInfo)
+ mc.cacheByFullName = make(map[string]*modelInfo)
+ mc.done = false
+}
+
+// ResetModelCache Clean model cache. Then you can re-RegisterModel.
+// Common use this api for test case.
+func ResetModelCache() {
+ modelCache.clean()
+}
diff --git a/orm/models_boot.go b/orm/models_boot.go
new file mode 100644
index 00000000..8c56b3c4
--- /dev/null
+++ b/orm/models_boot.go
@@ -0,0 +1,347 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+ "runtime/debug"
+ "strings"
+)
+
+// register models.
+// PrefixOrSuffix means table name prefix or suffix.
+// isPrefix whether the prefix is prefix or suffix
+func registerModel(PrefixOrSuffix string, model interface{}, isPrefix bool) {
+ val := reflect.ValueOf(model)
+ typ := reflect.Indirect(val).Type()
+
+ if val.Kind() != reflect.Ptr {
+ panic(fmt.Errorf(" cannot use non-ptr model struct `%s`", getFullName(typ)))
+ }
+ // For this case:
+ // u := &User{}
+ // registerModel(&u)
+ if typ.Kind() == reflect.Ptr {
+ panic(fmt.Errorf(" only allow ptr model struct, it looks you use two reference to the struct `%s`", typ))
+ }
+
+ table := getTableName(val)
+
+ if PrefixOrSuffix != "" {
+ if isPrefix {
+ table = PrefixOrSuffix + table
+ } else {
+ table = table + PrefixOrSuffix
+ }
+ }
+ // models's fullname is pkgpath + struct name
+ name := getFullName(typ)
+ if _, ok := modelCache.getByFullName(name); ok {
+ fmt.Printf(" model `%s` repeat register, must be unique\n", name)
+ os.Exit(2)
+ }
+
+ if _, ok := modelCache.get(table); ok {
+ fmt.Printf(" table name `%s` repeat register, must be unique\n", table)
+ os.Exit(2)
+ }
+
+ mi := newModelInfo(val)
+ if mi.fields.pk == nil {
+ outFor:
+ for _, fi := range mi.fields.fieldsDB {
+ if strings.ToLower(fi.name) == "id" {
+ switch fi.addrValue.Elem().Kind() {
+ case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64:
+ fi.auto = true
+ fi.pk = true
+ mi.fields.pk = fi
+ break outFor
+ }
+ }
+ }
+
+ if mi.fields.pk == nil {
+ fmt.Printf(" `%s` needs a primary key field, default is to use 'id' if not set\n", name)
+ os.Exit(2)
+ }
+
+ }
+
+ mi.table = table
+ mi.pkg = typ.PkgPath()
+ mi.model = model
+ mi.manual = true
+
+ modelCache.set(table, mi)
+}
+
+// bootstrap models
+func bootStrap() {
+ if modelCache.done {
+ return
+ }
+ var (
+ err error
+ models map[string]*modelInfo
+ )
+ if dataBaseCache.getDefault() == nil {
+ err = fmt.Errorf("must have one register DataBase alias named `default`")
+ goto end
+ }
+
+ // set rel and reverse model
+ // RelManyToMany set the relTable
+ models = modelCache.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.columns {
+ if fi.rel || fi.reverse {
+ elm := fi.addrValue.Type().Elem()
+ if fi.fieldType == RelReverseMany || fi.fieldType == RelManyToMany {
+ elm = elm.Elem()
+ }
+ // check the rel or reverse model already register
+ name := getFullName(elm)
+ mii, ok := modelCache.getByFullName(name)
+ if !ok || mii.pkg != elm.PkgPath() {
+ err = fmt.Errorf("can not find rel in field `%s`, `%s` may be miss register", fi.fullName, elm.String())
+ goto end
+ }
+ fi.relModelInfo = mii
+
+ switch fi.fieldType {
+ case RelManyToMany:
+ if fi.relThrough != "" {
+ if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) {
+ pn := fi.relThrough[:i]
+ rmi, ok := modelCache.getByFullName(fi.relThrough)
+ if !ok || pn != rmi.pkg {
+ err = fmt.Errorf("field `%s` wrong rel_through value `%s` cannot find table", fi.fullName, fi.relThrough)
+ goto end
+ }
+ fi.relThroughModelInfo = rmi
+ fi.relTable = rmi.table
+ } else {
+ err = fmt.Errorf("field `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
+ goto end
+ }
+ } else {
+ i := newM2MModelInfo(mi, mii)
+ if fi.relTable != "" {
+ i.table = fi.relTable
+ }
+ if v := modelCache.set(i.table, i); v != nil {
+ err = fmt.Errorf("the rel table name `%s` already registered, cannot be use, please change one", fi.relTable)
+ goto end
+ }
+ fi.relTable = i.table
+ fi.relThroughModelInfo = i
+ }
+
+ fi.relThroughModelInfo.isThrough = true
+ }
+ }
+ }
+ }
+
+ // check the rel filed while the relModelInfo also has filed point to current model
+ // if not exist, add a new field to the relModelInfo
+ models = modelCache.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.fieldsRel {
+ switch fi.fieldType {
+ case RelForeignKey, RelOneToOne, RelManyToMany:
+ inModel := false
+ for _, ffi := range fi.relModelInfo.fields.fieldsReverse {
+ if ffi.relModelInfo == mi {
+ inModel = true
+ break
+ }
+ }
+ if !inModel {
+ rmi := fi.relModelInfo
+ ffi := new(fieldInfo)
+ ffi.name = mi.name
+ ffi.column = ffi.name
+ ffi.fullName = rmi.fullName + "." + ffi.name
+ ffi.reverse = true
+ ffi.relModelInfo = mi
+ ffi.mi = rmi
+ if fi.fieldType == RelOneToOne {
+ ffi.fieldType = RelReverseOne
+ } else {
+ ffi.fieldType = RelReverseMany
+ }
+ if !rmi.fields.Add(ffi) {
+ added := false
+ for cnt := 0; cnt < 5; cnt++ {
+ ffi.name = fmt.Sprintf("%s%d", mi.name, cnt)
+ ffi.column = ffi.name
+ ffi.fullName = rmi.fullName + "." + ffi.name
+ if added = rmi.fields.Add(ffi); added {
+ break
+ }
+ }
+ if !added {
+ panic(fmt.Errorf("cannot generate auto reverse field info `%s` to `%s`", fi.fullName, ffi.fullName))
+ }
+ }
+ }
+ }
+ }
+ }
+
+ models = modelCache.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.fieldsRel {
+ switch fi.fieldType {
+ case RelManyToMany:
+ for _, ffi := range fi.relThroughModelInfo.fields.fieldsRel {
+ switch ffi.fieldType {
+ case RelOneToOne, RelForeignKey:
+ if ffi.relModelInfo == fi.relModelInfo {
+ fi.reverseFieldInfoTwo = ffi
+ }
+ if ffi.relModelInfo == mi {
+ fi.reverseField = ffi.name
+ fi.reverseFieldInfo = ffi
+ }
+ }
+ }
+ if fi.reverseFieldInfoTwo == nil {
+ err = fmt.Errorf("can not find m2m field for m2m model `%s`, ensure your m2m model defined correct",
+ fi.relThroughModelInfo.fullName)
+ goto end
+ }
+ }
+ }
+ }
+
+ models = modelCache.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.fieldsReverse {
+ switch fi.fieldType {
+ case RelReverseOne:
+ found := false
+ mForA:
+ for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelOneToOne] {
+ if ffi.relModelInfo == mi {
+ found = true
+ fi.reverseField = ffi.name
+ fi.reverseFieldInfo = ffi
+
+ ffi.reverseField = fi.name
+ ffi.reverseFieldInfo = fi
+ break mForA
+ }
+ }
+ if !found {
+ err = fmt.Errorf("reverse field `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
+ goto end
+ }
+ case RelReverseMany:
+ found := false
+ mForB:
+ for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelForeignKey] {
+ if ffi.relModelInfo == mi {
+ found = true
+ fi.reverseField = ffi.name
+ fi.reverseFieldInfo = ffi
+
+ ffi.reverseField = fi.name
+ ffi.reverseFieldInfo = fi
+
+ break mForB
+ }
+ }
+ if !found {
+ mForC:
+ for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelManyToMany] {
+ conditions := fi.relThrough != "" && fi.relThrough == ffi.relThrough ||
+ fi.relTable != "" && fi.relTable == ffi.relTable ||
+ fi.relThrough == "" && fi.relTable == ""
+ if ffi.relModelInfo == mi && conditions {
+ found = true
+
+ fi.reverseField = ffi.reverseFieldInfoTwo.name
+ fi.reverseFieldInfo = ffi.reverseFieldInfoTwo
+ fi.relThroughModelInfo = ffi.relThroughModelInfo
+ fi.reverseFieldInfoTwo = ffi.reverseFieldInfo
+ fi.reverseFieldInfoM2M = ffi
+ ffi.reverseFieldInfoM2M = fi
+
+ break mForC
+ }
+ }
+ }
+ if !found {
+ err = fmt.Errorf("reverse field for `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
+ goto end
+ }
+ }
+ }
+ }
+
+end:
+ if err != nil {
+ fmt.Println(err)
+ debug.PrintStack()
+ os.Exit(2)
+ }
+}
+
+// RegisterModel register models
+func RegisterModel(models ...interface{}) {
+ if modelCache.done {
+ panic(fmt.Errorf("RegisterModel must be run before BootStrap"))
+ }
+ RegisterModelWithPrefix("", models...)
+}
+
+// RegisterModelWithPrefix register models with a prefix
+func RegisterModelWithPrefix(prefix string, models ...interface{}) {
+ if modelCache.done {
+ panic(fmt.Errorf("RegisterModelWithPrefix must be run before BootStrap"))
+ }
+
+ for _, model := range models {
+ registerModel(prefix, model, true)
+ }
+}
+
+// RegisterModelWithSuffix register models with a suffix
+func RegisterModelWithSuffix(suffix string, models ...interface{}) {
+ if modelCache.done {
+ panic(fmt.Errorf("RegisterModelWithSuffix must be run before BootStrap"))
+ }
+
+ for _, model := range models {
+ registerModel(suffix, model, false)
+ }
+}
+
+// BootStrap bootstrap models.
+// make all model parsed and can not add more models
+func BootStrap() {
+ modelCache.Lock()
+ defer modelCache.Unlock()
+ if modelCache.done {
+ return
+ }
+ bootStrap()
+ modelCache.done = true
+}
diff --git a/client/orm/models_fields.go b/orm/models_fields.go
similarity index 100%
rename from client/orm/models_fields.go
rename to orm/models_fields.go
diff --git a/client/orm/models_info_f.go b/orm/models_info_f.go
similarity index 97%
rename from client/orm/models_info_f.go
rename to orm/models_info_f.go
index 7152fada..7044b0bd 100644
--- a/client/orm/models_info_f.go
+++ b/orm/models_info_f.go
@@ -137,7 +137,6 @@ type fieldInfo struct {
isFielder bool // implement Fielder interface
onDelete string
description string
- timePrecision *int
}
// new field info
@@ -178,7 +177,7 @@ func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField, mN
decimals := tags["decimals"]
size := tags["size"]
onDelete := tags["on_delete"]
- precision := tags["precision"]
+
initial.Clear()
if v, ok := tags["default"]; ok {
initial.Set(v)
@@ -378,18 +377,6 @@ checkType:
fi.index = false
fi.unique = false
case TypeTimeField, TypeDateField, TypeDateTimeField:
- if fieldType == TypeDateTimeField {
- if precision != "" {
- v, e := StrTo(precision).Int()
- if e != nil {
- err = fmt.Errorf("convert %s to int error:%v", precision, e)
- } else {
- fi.timePrecision = &v
- }
- }
-
- }
-
if attrs["auto_now"] {
fi.autoNow = true
} else if attrs["auto_now_add"] {
diff --git a/client/orm/models_info_m.go b/orm/models_info_m.go
similarity index 98%
rename from client/orm/models_info_m.go
rename to orm/models_info_m.go
index c450239c..a4d733b6 100644
--- a/client/orm/models_info_m.go
+++ b/orm/models_info_m.go
@@ -29,7 +29,7 @@ type modelInfo struct {
model interface{}
fields *fields
manual bool
- addrField reflect.Value // store the original struct value
+ addrField reflect.Value //store the original struct value
uniques []string
isThrough bool
}
diff --git a/client/orm/models_test.go b/orm/models_test.go
similarity index 66%
rename from client/orm/models_test.go
rename to orm/models_test.go
index d5aa2fa0..e3a635f2 100644
--- a/client/orm/models_test.go
+++ b/orm/models_test.go
@@ -53,24 +53,18 @@ func (e *SliceStringField) FieldType() int {
}
func (e *SliceStringField) SetRaw(value interface{}) error {
- f := func(str string) {
- if len(str) > 0 {
- parts := strings.Split(str, ",")
+ switch d := value.(type) {
+ case []string:
+ e.Set(d)
+ case string:
+ if len(d) > 0 {
+ parts := strings.Split(d, ",")
v := make([]string, 0, len(parts))
for _, p := range parts {
v = append(v, strings.TrimSpace(p))
}
e.Set(v)
}
- }
-
- switch d := value.(type) {
- case []string:
- e.Set(d)
- case string:
- f(d)
- case []byte:
- f(string(d))
default:
return fmt.Errorf(" unknown value `%v`", value)
}
@@ -102,8 +96,6 @@ func (e *JSONFieldTest) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
return json.Unmarshal([]byte(d), e)
- case []byte:
- return json.Unmarshal(d, e)
default:
return fmt.Errorf(" unknown value `%v`", value)
}
@@ -143,56 +135,55 @@ type Data struct {
}
type DataNull struct {
- ID int `orm:"column(id)"`
- Boolean bool `orm:"null"`
- Char string `orm:"null;size(50)"`
- Text string `orm:"null;type(text)"`
- JSON string `orm:"type(json);null"`
- Jsonb string `orm:"type(jsonb);null"`
- Time time.Time `orm:"null;type(time)"`
- Date time.Time `orm:"null;type(date)"`
- DateTime time.Time `orm:"null;column(datetime)"`
- DateTimePrecision time.Time `orm:"null;type(datetime);precision(4)"`
- Byte byte `orm:"null"`
- Rune rune `orm:"null"`
- Int int `orm:"null"`
- Int8 int8 `orm:"null"`
- Int16 int16 `orm:"null"`
- Int32 int32 `orm:"null"`
- Int64 int64 `orm:"null"`
- Uint uint `orm:"null"`
- Uint8 uint8 `orm:"null"`
- Uint16 uint16 `orm:"null"`
- Uint32 uint32 `orm:"null"`
- Uint64 uint64 `orm:"null"`
- Float32 float32 `orm:"null"`
- Float64 float64 `orm:"null"`
- Decimal float64 `orm:"digits(8);decimals(4);null"`
- NullString sql.NullString `orm:"null"`
- NullBool sql.NullBool `orm:"null"`
- NullFloat64 sql.NullFloat64 `orm:"null"`
- NullInt64 sql.NullInt64 `orm:"null"`
- BooleanPtr *bool `orm:"null"`
- CharPtr *string `orm:"null;size(50)"`
- TextPtr *string `orm:"null;type(text)"`
- BytePtr *byte `orm:"null"`
- RunePtr *rune `orm:"null"`
- IntPtr *int `orm:"null"`
- Int8Ptr *int8 `orm:"null"`
- Int16Ptr *int16 `orm:"null"`
- Int32Ptr *int32 `orm:"null"`
- Int64Ptr *int64 `orm:"null"`
- UintPtr *uint `orm:"null"`
- Uint8Ptr *uint8 `orm:"null"`
- Uint16Ptr *uint16 `orm:"null"`
- Uint32Ptr *uint32 `orm:"null"`
- Uint64Ptr *uint64 `orm:"null"`
- Float32Ptr *float32 `orm:"null"`
- Float64Ptr *float64 `orm:"null"`
- DecimalPtr *float64 `orm:"digits(8);decimals(4);null"`
- TimePtr *time.Time `orm:"null;type(time)"`
- DatePtr *time.Time `orm:"null;type(date)"`
- DateTimePtr *time.Time `orm:"null"`
+ ID int `orm:"column(id)"`
+ Boolean bool `orm:"null"`
+ Char string `orm:"null;size(50)"`
+ Text string `orm:"null;type(text)"`
+ JSON string `orm:"type(json);null"`
+ Jsonb string `orm:"type(jsonb);null"`
+ Time time.Time `orm:"null;type(time)"`
+ Date time.Time `orm:"null;type(date)"`
+ DateTime time.Time `orm:"null;column(datetime)"`
+ Byte byte `orm:"null"`
+ Rune rune `orm:"null"`
+ Int int `orm:"null"`
+ Int8 int8 `orm:"null"`
+ Int16 int16 `orm:"null"`
+ Int32 int32 `orm:"null"`
+ Int64 int64 `orm:"null"`
+ Uint uint `orm:"null"`
+ Uint8 uint8 `orm:"null"`
+ Uint16 uint16 `orm:"null"`
+ Uint32 uint32 `orm:"null"`
+ Uint64 uint64 `orm:"null"`
+ Float32 float32 `orm:"null"`
+ Float64 float64 `orm:"null"`
+ Decimal float64 `orm:"digits(8);decimals(4);null"`
+ NullString sql.NullString `orm:"null"`
+ NullBool sql.NullBool `orm:"null"`
+ NullFloat64 sql.NullFloat64 `orm:"null"`
+ NullInt64 sql.NullInt64 `orm:"null"`
+ BooleanPtr *bool `orm:"null"`
+ CharPtr *string `orm:"null;size(50)"`
+ TextPtr *string `orm:"null;type(text)"`
+ BytePtr *byte `orm:"null"`
+ RunePtr *rune `orm:"null"`
+ IntPtr *int `orm:"null"`
+ Int8Ptr *int8 `orm:"null"`
+ Int16Ptr *int16 `orm:"null"`
+ Int32Ptr *int32 `orm:"null"`
+ Int64Ptr *int64 `orm:"null"`
+ UintPtr *uint `orm:"null"`
+ Uint8Ptr *uint8 `orm:"null"`
+ Uint16Ptr *uint16 `orm:"null"`
+ Uint32Ptr *uint32 `orm:"null"`
+ Uint64Ptr *uint64 `orm:"null"`
+ Float32Ptr *float32 `orm:"null"`
+ Float64Ptr *float64 `orm:"null"`
+ DecimalPtr *float64 `orm:"digits(8);decimals(4);null"`
+ TimePtr *time.Time `orm:"null;type(time)"`
+ DatePtr *time.Time `orm:"null;type(date)"`
+ DateTimePtr *time.Time `orm:"null"`
}
type String string
@@ -240,21 +231,6 @@ type UserBig struct {
Name string
}
-type TM struct {
- ID int `orm:"column(id)"`
- TMPrecision1 time.Time `orm:"type(datetime);precision(3)"`
- TMPrecision2 time.Time `orm:"auto_now_add;type(datetime);precision(4)"`
-}
-
-func (t *TM) TableName() string {
- return "tm"
-}
-
-func NewTM() *TM {
- obj := new(TM)
- return obj
-}
-
type User struct {
ID int `orm:"column(id)"`
UserName string `orm:"size(30);unique"`
@@ -311,14 +287,13 @@ func NewProfile() *Profile {
}
type Post struct {
- ID int `orm:"column(id)"`
- User *User `orm:"rel(fk)"`
- Title string `orm:"size(60)"`
- Content string `orm:"type(text)"`
- 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)"`
+ ID int `orm:"column(id)"`
+ User *User `orm:"rel(fk)"`
+ Title string `orm:"size(60)"`
+ Content string `orm:"type(text)"`
+ Created time.Time `orm:"auto_now_add"`
+ Updated time.Time `orm:"auto_now"`
+ Tags []*Tag `orm:"rel(m2m);rel_through(github.com/astaxie/beego/orm.PostTags)"`
}
func (u *Post) TableIndex() [][]string {
@@ -376,7 +351,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/astaxie/beego/orm.GroupPermissions)"`
}
type GroupPermissions struct {
@@ -405,15 +380,6 @@ type InLine struct {
Email string
}
-type Index struct {
- // Common Fields
- Id int `orm:"column(id)"`
-
- // Other Fields
- F1 int `orm:"column(f1);index"`
- F2 int `orm:"column(f2);index"`
-}
-
func NewInLine() *InLine {
return new(InLine)
}
@@ -445,11 +411,6 @@ type PtrPk struct {
Positive bool
}
-type StrPk struct {
- Id string `orm:"column(id);size(64);pk"`
- Value string
-}
-
var DBARGS = struct {
Driver string
Source string
@@ -485,7 +446,7 @@ var (
usage:
- go get -u github.com/astaxie/beego/client/orm
+ go get -u github.com/astaxie/beego/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,43 +456,38 @@ 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/astaxie/beego/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/astaxie/beego/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/astaxie/beego/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/astaxie/beego/orm
`
)
func init() {
- // Debug, _ = StrTo(DBARGS.Debug).Bool()
- Debug = true
+ Debug, _ = StrTo(DBARGS.Debug).Bool()
if DBARGS.Driver == "" || DBARGS.Source == "" {
fmt.Println(helpinfo)
os.Exit(2)
}
- err := RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, MaxIdleConnections(20))
-
- if err != nil {
- panic(fmt.Sprintf("can not register database: %v", err))
- }
+ RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, 20)
alias := getDbAlias("default")
if alias.Driver == DRMySQL {
diff --git a/client/orm/models_utils.go b/orm/models_utils.go
similarity index 93%
rename from client/orm/models_utils.go
rename to orm/models_utils.go
index 950ca243..71127a6b 100644
--- a/client/orm/models_utils.go
+++ b/orm/models_utils.go
@@ -45,7 +45,6 @@ var supportTag = map[string]int{
"on_delete": 2,
"type": 2,
"description": 2,
- "precision": 2,
}
// get reflect.Type name with package path.
@@ -107,18 +106,6 @@ func getTableUnique(val reflect.Value) [][]string {
return nil
}
-// get whether the table needs to be created for the database alias
-func isApplicableTableForDB(val reflect.Value, db string) bool {
- fun := val.MethodByName("IsApplicableTableForDB")
- if fun.IsValid() {
- vals := fun.Call([]reflect.Value{reflect.ValueOf(db)})
- if len(vals) > 0 && vals[0].Kind() == reflect.Bool {
- return vals[0].Bool()
- }
- }
- return true
-}
-
// get snaked column name
func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string {
column := col
diff --git a/client/orm/orm.go b/orm/orm.go
similarity index 57%
rename from client/orm/orm.go
rename to orm/orm.go
index a83faeb2..0551b1cd 100644
--- a/client/orm/orm.go
+++ b/orm/orm.go
@@ -21,7 +21,7 @@
//
// import (
// "fmt"
-// "github.com/astaxie/beego/client/orm"
+// "github.com/astaxie/beego/orm"
// _ "github.com/go-sql-driver/mysql" // import your used driver
// )
//
@@ -60,12 +60,8 @@ import (
"fmt"
"os"
"reflect"
+ "sync"
"time"
-
- "github.com/astaxie/beego/client/orm/hints"
- "github.com/astaxie/beego/core/utils"
-
- "github.com/astaxie/beego/core/logs"
)
// DebugQueries define the debug
@@ -80,14 +76,13 @@ var (
DefaultRowsLimit = -1
DefaultRelsDepth = 2
DefaultTimeLoc = time.Local
- ErrTxDone = errors.New(" transaction already done")
+ ErrTxHasBegan = errors.New(" transaction already begin")
+ ErrTxDone = errors.New(" transaction not begin")
ErrMultiRows = errors.New(" return multi rows")
ErrNoRows = errors.New(" no row found")
ErrStmtClosed = errors.New(" stmt already closed")
ErrArgs = errors.New(" args error may be empty")
ErrNotImplement = errors.New("have not implement")
-
- ErrLastInsertIdUnavailable = errors.New(" last insert id is unavailable")
)
// Params stores the Params
@@ -96,17 +91,16 @@ type Params map[string]interface{}
// ParamsList stores paramslist
type ParamsList []interface{}
-type ormBase struct {
+type orm struct {
alias *alias
db dbQuerier
+ isTx bool
}
-var _ DQL = new(ormBase)
-var _ DML = new(ormBase)
-var _ DriverGetter = new(ormBase)
+var _ Ormer = new(orm)
// get model info and model reflect value
-func (o *ormBase) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) {
+func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) {
val := reflect.ValueOf(md)
ind = reflect.Indirect(val)
typ := ind.Type()
@@ -121,7 +115,7 @@ func (o *ormBase) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind ref
}
// get field info from model info by given field name
-func (o *ormBase) getFieldInfo(mi *modelInfo, name string) *fieldInfo {
+func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo {
fi, ok := mi.fields.GetByAny(name)
if !ok {
panic(fmt.Errorf(" cannot find field `%s` for model `%s`", name, mi.fullName))
@@ -130,42 +124,33 @@ func (o *ormBase) getFieldInfo(mi *modelInfo, name string) *fieldInfo {
}
// read data to model
-func (o *ormBase) Read(md interface{}, cols ...string) error {
- return o.ReadWithCtx(context.Background(), md, cols...)
-}
-func (o *ormBase) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+func (o *orm) Read(md interface{}, cols ...string) error {
mi, ind := o.getMiInd(md, true)
return o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, false)
}
// read data to model, like Read(), but use "SELECT FOR UPDATE" form
-func (o *ormBase) ReadForUpdate(md interface{}, cols ...string) error {
- return o.ReadForUpdateWithCtx(context.Background(), md, cols...)
-}
-func (o *ormBase) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+func (o *orm) ReadForUpdate(md interface{}, cols ...string) error {
mi, ind := o.getMiInd(md, true)
return o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, true)
}
// Try to read a row from the database, or insert one if it doesn't exist
-func (o *ormBase) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
- return o.ReadOrCreateWithCtx(context.Background(), md, col1, cols...)
-}
-func (o *ormBase) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
+func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
cols = append([]string{col1}, cols...)
mi, ind := o.getMiInd(md, true)
err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, false)
if err == ErrNoRows {
// Create
- id, err := o.InsertWithCtx(ctx, md)
- return err == nil, id, err
+ id, err := o.Insert(md)
+ return (err == nil), id, err
}
id, vid := int64(0), ind.FieldByIndex(mi.fields.pk.fieldIndex)
if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
id = int64(vid.Uint())
} else if mi.fields.pk.rel {
- return o.ReadOrCreateWithCtx(ctx, vid.Interface(), mi.fields.pk.relModelInfo.fields.pk.name)
+ return o.ReadOrCreate(vid.Interface(), mi.fields.pk.relModelInfo.fields.pk.name)
} else {
id = vid.Int()
}
@@ -174,10 +159,7 @@ func (o *ormBase) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1
}
// insert model data to database
-func (o *ormBase) Insert(md interface{}) (int64, error) {
- return o.InsertWithCtx(context.Background(), md)
-}
-func (o *ormBase) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
+func (o *orm) Insert(md interface{}) (int64, error) {
mi, ind := o.getMiInd(md, true)
id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ)
if err != nil {
@@ -190,7 +172,7 @@ func (o *ormBase) InsertWithCtx(ctx context.Context, md interface{}) (int64, err
}
// set auto pk field
-func (o *ormBase) setPk(mi *modelInfo, ind reflect.Value, id int64) {
+func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) {
if mi.fields.pk.auto {
if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(uint64(id))
@@ -201,10 +183,7 @@ func (o *ormBase) setPk(mi *modelInfo, ind reflect.Value, id int64) {
}
// insert some models to database
-func (o *ormBase) InsertMulti(bulk int, mds interface{}) (int64, error) {
- return o.InsertMultiWithCtx(context.Background(), bulk, mds)
-}
-func (o *ormBase) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
+func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) {
var cnt int64
sind := reflect.Indirect(reflect.ValueOf(mds))
@@ -239,10 +218,7 @@ func (o *ormBase) InsertMultiWithCtx(ctx context.Context, bulk int, mds interfac
}
// InsertOrUpdate data to database
-func (o *ormBase) InsertOrUpdate(md interface{}, colConflictAndArgs ...string) (int64, error) {
- return o.InsertOrUpdateWithCtx(context.Background(), md, colConflictAndArgs...)
-}
-func (o *ormBase) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
+func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
mi, ind := o.getMiInd(md, true)
id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias, colConflitAndArgs...)
if err != nil {
@@ -256,20 +232,14 @@ func (o *ormBase) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, col
// update model to database.
// cols set the columns those want to update.
-func (o *ormBase) Update(md interface{}, cols ...string) (int64, error) {
- return o.UpdateWithCtx(context.Background(), md, cols...)
-}
-func (o *ormBase) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+func (o *orm) Update(md interface{}, cols ...string) (int64, error) {
mi, ind := o.getMiInd(md, true)
return o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ, cols)
}
// delete model in database
// cols shows the delete conditions values read from. default is pk
-func (o *ormBase) Delete(md interface{}, cols ...string) (int64, error) {
- return o.DeleteWithCtx(context.Background(), md, cols...)
-}
-func (o *ormBase) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+func (o *orm) Delete(md interface{}, cols ...string) (int64, error) {
mi, ind := o.getMiInd(md, true)
num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ, cols)
if err != nil {
@@ -282,10 +252,7 @@ func (o *ormBase) DeleteWithCtx(ctx context.Context, md interface{}, cols ...str
}
// create a models to models queryer
-func (o *ormBase) QueryM2M(md interface{}, name string) QueryM2Mer {
- return o.QueryM2MWithCtx(context.Background(), md, name)
-}
-func (o *ormBase) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer {
+func (o *orm) QueryM2M(md interface{}, name string) QueryM2Mer {
mi, ind := o.getMiInd(md, true)
fi := o.getFieldInfo(mi, name)
@@ -307,38 +274,32 @@ func (o *ormBase) QueryM2MWithCtx(ctx context.Context, md interface{}, name stri
// for _,tag := range post.Tags{...}
//
// make sure the relation is defined in model struct tags.
-func (o *ormBase) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
- return o.LoadRelatedWithCtx(context.Background(), md, name, args...)
-}
-func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
- _, fi, ind, qs := o.queryRelated(md, name)
+func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
+ _, fi, ind, qseter := o.queryRelated(md, name)
+
+ qs := qseter.(*querySet)
var relDepth int
var limit, offset int64
var order string
-
- kvs := utils.NewKVs(args...)
- kvs.IfContains(hints.KeyRelDepth, func(value interface{}) {
- if v, ok := value.(bool); ok {
- if v {
- relDepth = DefaultRelsDepth
+ for i, arg := range args {
+ switch i {
+ case 0:
+ if v, ok := arg.(bool); ok {
+ if v {
+ relDepth = DefaultRelsDepth
+ }
+ } else if v, ok := arg.(int); ok {
+ relDepth = v
}
- } else if v, ok := value.(int); ok {
- relDepth = v
+ case 1:
+ limit = ToInt64(arg)
+ case 2:
+ offset = ToInt64(arg)
+ case 3:
+ order, _ = arg.(string)
}
- }).IfContains(hints.KeyLimit, func(value interface{}) {
- if v, ok := value.(int64); ok {
- limit = v
- }
- }).IfContains(hints.KeyOffset, func(value interface{}) {
- if v, ok := value.(int64); ok {
- offset = v
- }
- }).IfContains(hints.KeyOrderBy, func(value interface{}) {
- if v, ok := value.(string); ok {
- order = v
- }
- })
+ }
switch fi.fieldType {
case RelOneToOne, RelForeignKey, RelReverseOne:
@@ -374,8 +335,20 @@ func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name s
return nums, err
}
+// return a QuerySeter for related models to md model.
+// it can do all, update, delete in QuerySeter.
+// example:
+// qs := orm.QueryRelated(post,"Tag")
+// qs.All(&[]*Tag{})
+//
+func (o *orm) QueryRelated(md interface{}, name string) QuerySeter {
+ // is this api needed ?
+ _, _, _, qs := o.queryRelated(md, name)
+ return qs
+}
+
// get QuerySeter for related models to md model
-func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, *querySet) {
+func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) {
mi, ind := o.getMiInd(md, true)
fi := o.getFieldInfo(mi, name)
@@ -407,7 +380,7 @@ func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldI
}
// get reverse relation QuerySeter
-func (o *ormBase) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
+func (o *orm) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
switch fi.fieldType {
case RelReverseOne, RelReverseMany:
default:
@@ -428,7 +401,7 @@ func (o *ormBase) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *qu
}
// get relation QuerySeter
-func (o *ormBase) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
+func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
switch fi.fieldType {
case RelOneToOne, RelForeignKey, RelManyToMany:
default:
@@ -450,10 +423,7 @@ func (o *ormBase) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *queryS
// return a QuerySeter for table operations.
// table name can be string or struct.
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
-func (o *ormBase) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
- return o.QueryTableWithCtx(context.Background(), ptrStructOrTableName)
-}
-func (o *ormBase) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) (qs QuerySeter) {
+func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
var name string
if table, ok := ptrStructOrTableName.(string); ok {
name = nameStrategyMap[defaultNameStrategy](table)
@@ -472,21 +442,89 @@ func (o *ormBase) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName in
return
}
-// return a raw query seter for raw sql string.
-func (o *ormBase) Raw(query string, args ...interface{}) RawSeter {
- return o.RawWithCtx(context.Background(), query, args...)
+// switch to another registered database driver by given name.
+func (o *orm) Using(name string) error {
+ if o.isTx {
+ panic(fmt.Errorf(" transaction has been start, cannot change db"))
+ }
+ if al, ok := dataBaseCache.get(name); ok {
+ o.alias = al
+ if Debug {
+ o.db = newDbQueryLog(al, al.DB)
+ } else {
+ o.db = al.DB
+ }
+ } else {
+ return fmt.Errorf(" unknown db alias name `%s`", name)
+ }
+ return nil
}
-func (o *ormBase) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
+
+// begin transaction
+func (o *orm) Begin() error {
+ return o.BeginTx(context.Background(), nil)
+}
+
+func (o *orm) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
+ if o.isTx {
+ return ErrTxHasBegan
+ }
+ var tx *sql.Tx
+ tx, err := o.db.(txer).BeginTx(ctx, opts)
+ if err != nil {
+ return err
+ }
+ o.isTx = true
+ if Debug {
+ o.db.(*dbQueryLog).SetDB(tx)
+ } else {
+ o.db = tx
+ }
+ return nil
+}
+
+// commit transaction
+func (o *orm) Commit() error {
+ if !o.isTx {
+ return ErrTxDone
+ }
+ err := o.db.(txEnder).Commit()
+ if err == nil {
+ o.isTx = false
+ o.Using(o.alias.Name)
+ } else if err == sql.ErrTxDone {
+ return ErrTxDone
+ }
+ return err
+}
+
+// rollback transaction
+func (o *orm) Rollback() error {
+ if !o.isTx {
+ return ErrTxDone
+ }
+ err := o.db.(txEnder).Rollback()
+ if err == nil {
+ o.isTx = false
+ o.Using(o.alias.Name)
+ } else if err == sql.ErrTxDone {
+ return ErrTxDone
+ }
+ return err
+}
+
+// return a raw query seter for raw sql string.
+func (o *orm) Raw(query string, args ...interface{}) RawSeter {
return newRawSet(o, query, args)
}
// return current using database Driver
-func (o *ormBase) Driver() Driver {
+func (o *orm) Driver() Driver {
return driver(o.alias.Name)
}
// return sql.DBStats for current database
-func (o *ormBase) DBStats() *sql.DBStats {
+func (o *orm) DBStats() *sql.DBStats {
if o.alias != nil && o.alias.DB != nil {
stats := o.alias.DB.DB.Stats()
return &stats
@@ -494,134 +532,48 @@ func (o *ormBase) DBStats() *sql.DBStats {
return nil
}
-type orm struct {
- ormBase
-}
-
-var _ Ormer = new(orm)
-
-func (o *orm) Begin() (TxOrmer, error) {
- return o.BeginWithCtx(context.Background())
-}
-
-func (o *orm) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
- return o.BeginWithCtxAndOpts(ctx, nil)
-}
-
-func (o *orm) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
- return o.BeginWithCtxAndOpts(context.Background(), opts)
-}
-
-func (o *orm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
- tx, err := o.db.(txer).BeginTx(ctx, opts)
- if err != nil {
- return nil, err
- }
-
- _txOrm := &txOrm{
- ormBase: ormBase{
- alias: o.alias,
- db: &TxDB{tx: tx},
- },
- }
-
- var taskTxOrm TxOrmer = _txOrm
- return taskTxOrm, nil
-}
-
-func (o *orm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
- return o.DoTxWithCtx(context.Background(), task)
-}
-
-func (o *orm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
- return o.DoTxWithCtxAndOpts(ctx, nil, task)
-}
-
-func (o *orm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
- return o.DoTxWithCtxAndOpts(context.Background(), opts, task)
-}
-
-func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
- return doTxTemplate(o, ctx, opts, task)
-}
-
-func doTxTemplate(o TxBeginner, ctx context.Context, opts *sql.TxOptions,
- task func(ctx context.Context, txOrm TxOrmer) error) error {
- _txOrm, err := o.BeginWithCtxAndOpts(ctx, opts)
- if err != nil {
- return err
- }
- panicked := true
- defer func() {
- if panicked || err != nil {
- e := _txOrm.Rollback()
- if e != nil {
- logs.Error("rollback transaction failed: %v,%v", e, panicked)
- }
- } else {
- e := _txOrm.Commit()
- if e != nil {
- logs.Error("commit transaction failed: %v,%v", e, panicked)
- }
- }
- }()
- var taskTxOrm = _txOrm
- err = task(ctx, taskTxOrm)
- panicked = false
- return err
-}
-
-type txOrm struct {
- ormBase
-}
-
-var _ TxOrmer = new(txOrm)
-
-func (t *txOrm) Commit() error {
- return t.db.(txEnder).Commit()
-}
-
-func (t *txOrm) Rollback() error {
- return t.db.(txEnder).Rollback()
-}
-
// NewOrm create new orm
func NewOrm() Ormer {
BootStrap() // execute only once
- return NewOrmUsingDB(`default`)
-}
-// NewOrmUsingDB create new orm with the name
-func NewOrmUsingDB(aliasName string) Ormer {
- if al, ok := dataBaseCache.get(aliasName); ok {
- return newDBWithAlias(al)
- } else {
- panic(fmt.Errorf(" unknown db alias name `%s`", aliasName))
+ o := new(orm)
+ err := o.Using("default")
+ if err != nil {
+ panic(err)
}
+ return o
}
// NewOrmWithDB create a new ormer object with specify *sql.DB for query
-func NewOrmWithDB(driverName, aliasName string, db *sql.DB, params ...DBOption) (Ormer, error) {
- al, err := newAliasWithDb(aliasName, driverName, db, params...)
- if err != nil {
- return nil, err
+func NewOrmWithDB(driverName, aliasName string, db *sql.DB) (Ormer, error) {
+ var al *alias
+
+ if dr, ok := drivers[driverName]; ok {
+ al = new(alias)
+ al.DbBaser = dbBasers[dr]
+ al.Driver = dr
+ } else {
+ return nil, fmt.Errorf("driver name `%s` have not registered", driverName)
}
- return newDBWithAlias(al), nil
-}
+ al.Name = aliasName
+ al.DriverName = driverName
+ al.DB = &DB{
+ RWMutex: new(sync.RWMutex),
+ DB: db,
+ stmtDecorators: newStmtDecoratorLruWithEvict(),
+ }
+
+ detectTZ(al)
-func newDBWithAlias(al *alias) Ormer {
o := new(orm)
o.alias = al
if Debug {
- o.db = newDbQueryLog(al, al.DB)
+ o.db = newDbQueryLog(o.alias, db)
} else {
- o.db = al.DB
+ o.db = db
}
- if len(globalFilterChains) > 0 {
- return NewFilterOrmDecorator(o, globalFilterChains...)
- }
- return o
+ return o, nil
}
diff --git a/client/orm/orm_conds.go b/orm/orm_conds.go
similarity index 100%
rename from client/orm/orm_conds.go
rename to orm/orm_conds.go
diff --git a/client/orm/orm_log.go b/orm/orm_log.go
similarity index 88%
rename from client/orm/orm_log.go
rename to orm/orm_log.go
index d8df7e36..f107bb59 100644
--- a/client/orm/orm_log.go
+++ b/orm/orm_log.go
@@ -61,7 +61,7 @@ func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error
con += " - " + err.Error()
}
logMap["sql"] = fmt.Sprintf("%s-`%s`", query, strings.Join(cons, "`, `"))
- if LogFunc != nil {
+ if LogFunc != nil{
LogFunc(logMap)
}
DebugLog.Println(con)
@@ -127,7 +127,10 @@ var _ txer = new(dbQueryLog)
var _ txEnder = new(dbQueryLog)
func (d *dbQueryLog) Prepare(query string) (*sql.Stmt, error) {
- return d.PrepareContext(context.Background(), query)
+ a := time.Now()
+ stmt, err := d.db.Prepare(query)
+ debugLogQueies(d.alias, "db.Prepare", query, a, err)
+ return stmt, err
}
func (d *dbQueryLog) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
@@ -138,7 +141,10 @@ func (d *dbQueryLog) PrepareContext(ctx context.Context, query string) (*sql.Stm
}
func (d *dbQueryLog) Exec(query string, args ...interface{}) (sql.Result, error) {
- return d.ExecContext(context.Background(), query, args...)
+ a := time.Now()
+ res, err := d.db.Exec(query, args...)
+ debugLogQueies(d.alias, "db.Exec", query, a, err, args...)
+ return res, err
}
func (d *dbQueryLog) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
@@ -149,7 +155,10 @@ func (d *dbQueryLog) ExecContext(ctx context.Context, query string, args ...inte
}
func (d *dbQueryLog) Query(query string, args ...interface{}) (*sql.Rows, error) {
- return d.QueryContext(context.Background(), query, args...)
+ a := time.Now()
+ res, err := d.db.Query(query, args...)
+ debugLogQueies(d.alias, "db.Query", query, a, err, args...)
+ return res, err
}
func (d *dbQueryLog) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
@@ -160,7 +169,10 @@ func (d *dbQueryLog) QueryContext(ctx context.Context, query string, args ...int
}
func (d *dbQueryLog) QueryRow(query string, args ...interface{}) *sql.Row {
- return d.QueryRowContext(context.Background(), query, args...)
+ a := time.Now()
+ res := d.db.QueryRow(query, args...)
+ debugLogQueies(d.alias, "db.QueryRow", query, a, nil, args...)
+ return res
}
func (d *dbQueryLog) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
@@ -171,7 +183,10 @@ func (d *dbQueryLog) QueryRowContext(ctx context.Context, query string, args ...
}
func (d *dbQueryLog) Begin() (*sql.Tx, error) {
- return d.BeginTx(context.Background(), nil)
+ a := time.Now()
+ tx, err := d.db.(txer).Begin()
+ debugLogQueies(d.alias, "db.Begin", "START TRANSACTION", a, err)
+ return tx, err
}
func (d *dbQueryLog) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
diff --git a/client/orm/orm_object.go b/orm/orm_object.go
similarity index 96%
rename from client/orm/orm_object.go
rename to orm/orm_object.go
index 6f9798d3..de3181ce 100644
--- a/client/orm/orm_object.go
+++ b/orm/orm_object.go
@@ -22,7 +22,7 @@ import (
// an insert queryer struct
type insertSet struct {
mi *modelInfo
- orm *ormBase
+ orm *orm
stmt stmtQuerier
closed bool
}
@@ -70,7 +70,7 @@ func (o *insertSet) Close() error {
}
// create new insert queryer.
-func newInsertSet(orm *ormBase, mi *modelInfo) (Inserter, error) {
+func newInsertSet(orm *orm, mi *modelInfo) (Inserter, error) {
bi := new(insertSet)
bi.orm = orm
bi.mi = mi
diff --git a/client/orm/orm_querym2m.go b/orm/orm_querym2m.go
similarity index 97%
rename from client/orm/orm_querym2m.go
rename to orm/orm_querym2m.go
index 17e1b5d1..6a270a0d 100644
--- a/client/orm/orm_querym2m.go
+++ b/orm/orm_querym2m.go
@@ -129,7 +129,7 @@ func (o *queryM2M) Count() (int64, error) {
var _ QueryM2Mer = new(queryM2M)
// create new M2M queryer.
-func newQueryM2M(md interface{}, o *ormBase, mi *modelInfo, fi *fieldInfo, ind reflect.Value) QueryM2Mer {
+func newQueryM2M(md interface{}, o *orm, mi *modelInfo, fi *fieldInfo, ind reflect.Value) QueryM2Mer {
qm2m := new(queryM2M)
qm2m.md = md
qm2m.mi = mi
diff --git a/client/orm/orm_queryset.go b/orm/orm_queryset.go
similarity index 91%
rename from client/orm/orm_queryset.go
rename to orm/orm_queryset.go
index ed223e24..878b836b 100644
--- a/client/orm/orm_queryset.go
+++ b/orm/orm_queryset.go
@@ -17,8 +17,6 @@ package orm
import (
"context"
"fmt"
-
- "github.com/astaxie/beego/client/orm/hints"
)
type colValue struct {
@@ -73,10 +71,8 @@ type querySet struct {
groups []string
orders []string
distinct bool
- forUpdate bool
- useIndex int
- indexes []string
- orm *ormBase
+ forupdate bool
+ orm *orm
ctx context.Context
forContext bool
}
@@ -152,28 +148,7 @@ func (o querySet) Distinct() QuerySeter {
// add FOR UPDATE to SELECT
func (o querySet) ForUpdate() QuerySeter {
- o.forUpdate = true
- return &o
-}
-
-// ForceIndex force index for query
-func (o querySet) ForceIndex(indexes ...string) QuerySeter {
- o.useIndex = hints.KeyForceIndex
- o.indexes = indexes
- return &o
-}
-
-// UseIndex use index for query
-func (o querySet) UseIndex(indexes ...string) QuerySeter {
- o.useIndex = hints.KeyUseIndex
- o.indexes = indexes
- return &o
-}
-
-// IgnoreIndex ignore index for query
-func (o querySet) IgnoreIndex(indexes ...string) QuerySeter {
- o.useIndex = hints.KeyIgnoreIndex
- o.indexes = indexes
+ o.forupdate = true
return &o
}
@@ -317,7 +292,7 @@ func (o querySet) WithContext(ctx context.Context) QuerySeter {
}
// create new QuerySeter.
-func newQuerySet(orm *ormBase, mi *modelInfo) QuerySeter {
+func newQuerySet(orm *orm, mi *modelInfo) QuerySeter {
o := new(querySet)
o.mi = mi
o.orm = orm
diff --git a/client/orm/orm_raw.go b/orm/orm_raw.go
similarity index 91%
rename from client/orm/orm_raw.go
rename to orm/orm_raw.go
index e11e97fa..3325a7ea 100644
--- a/client/orm/orm_raw.go
+++ b/orm/orm_raw.go
@@ -19,8 +19,6 @@ import (
"fmt"
"reflect"
"time"
-
- "github.com/pkg/errors"
)
// raw sql string prepared statement
@@ -34,8 +32,7 @@ func (o *rawPrepare) Exec(args ...interface{}) (sql.Result, error) {
if o.closed {
return nil, ErrStmtClosed
}
- flatParams := getFlatParams(nil, args, o.rs.orm.alias.TZ)
- return o.stmt.Exec(flatParams...)
+ return o.stmt.Exec(args...)
}
func (o *rawPrepare) Close() error {
@@ -66,7 +63,7 @@ func newRawPreparer(rs *rawSet) (RawPreparer, error) {
type rawSet struct {
query string
args []interface{}
- orm *ormBase
+ orm *orm
}
var _ RawSeter = new(rawSet)
@@ -330,8 +327,6 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
return err
}
- structTagMap := make(map[reflect.StructTag]map[string]string)
-
defer rows.Close()
if rows.Next() {
@@ -373,50 +368,23 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
field.Set(mf)
field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
}
- if fi.isFielder {
- fd := field.Addr().Interface().(Fielder)
- err := fd.SetRaw(value)
- if err != nil {
- return errors.Errorf("set raw error:%s", err)
- }
- } else {
- o.setFieldValue(field, value)
- }
+ o.setFieldValue(field, value)
}
}
} else {
- // 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)
- }
-
- // thanks @Gazeboxu.
- tags := structTagMap[fe.Tag]
- if tags == nil {
- _, tags = parseStructTag(fe.Tag.Get(defaultStructTagName))
- structTagMap[fe.Tag] = tags
- }
- var col string
- if col = tags["column"]; col == "" {
- col = nameStrategyMap[nameStrategy](fe.Name)
- }
- if v, ok := columnsMp[col]; ok {
- value := reflect.ValueOf(v).Elem().Interface()
- o.setFieldValue(f, value)
- }
+ 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 = nameStrategyMap[nameStrategy](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)
}
} else {
@@ -541,15 +509,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
field.Set(mf)
field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
}
- if fi.isFielder {
- fd := field.Addr().Interface().(Fielder)
- err := fd.SetRaw(value)
- if err != nil {
- return 0, errors.Errorf("set raw error:%s", err)
- }
- } else {
- o.setFieldValue(field, value)
- }
+ o.setFieldValue(field, value)
}
}
} else {
@@ -898,7 +858,7 @@ func (o *rawSet) Prepare() (RawPreparer, error) {
return newRawPreparer(o)
}
-func newRawSet(orm *ormBase, query string, args []interface{}) RawSeter {
+func newRawSet(orm *orm, query string, args []interface{}) RawSeter {
o := new(rawSet)
o.query = query
o.args = args
diff --git a/client/orm/orm_test.go b/orm/orm_test.go
similarity index 89%
rename from client/orm/orm_test.go
rename to orm/orm_test.go
index 565f6c60..bdb430b6 100644
--- a/client/orm/orm_test.go
+++ b/orm/orm_test.go
@@ -30,10 +30,6 @@ import (
"strings"
"testing"
"time"
-
- "github.com/astaxie/beego/client/orm/hints"
-
- "github.com/stretchr/testify/assert"
)
var _ = os.PathSeparator
@@ -145,7 +141,6 @@ func getCaller(skip int) string {
return fmt.Sprintf("%s:%s:%d: \n%s", fn, funName, line, strings.Join(codes, "\n"))
}
-// Deprecated: Using stretchr/testify/assert
func throwFail(t *testing.T, err error, args ...interface{}) {
if err != nil {
con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
@@ -202,9 +197,6 @@ func TestSyncDb(t *testing.T) {
RegisterModel(new(IntegerPk))
RegisterModel(new(UintPk))
RegisterModel(new(PtrPk))
- RegisterModel(new(Index))
- RegisterModel(new(StrPk))
- RegisterModel(new(TM))
err := RunSyncdb("default", true, Debug)
throwFail(t, err)
@@ -229,9 +221,6 @@ func TestRegisterModels(t *testing.T) {
RegisterModel(new(IntegerPk))
RegisterModel(new(UintPk))
RegisterModel(new(PtrPk))
- RegisterModel(new(Index))
- RegisterModel(new(StrPk))
- RegisterModel(new(TM))
BootStrap()
@@ -305,34 +294,19 @@ func TestDataTypes(t *testing.T) {
vu := e.Interface()
switch name {
case "Date":
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
case "DateTime":
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
case "Time":
- assert.True(t, vu.(time.Time).In(DefaultTimeLoc).Sub(value.(time.Time).In(DefaultTimeLoc)) <= time.Second)
- break
- default:
- assert.Equal(t, value, vu)
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
}
+ throwFail(t, AssertIs(vu == value, true), value, vu)
}
}
-func TestTM(t *testing.T) {
- // The precision of sqlite is not implemented
- if dORM.Driver().Type() == 2 {
- return
- }
- var recTM TM
- tm := NewTM()
- tm.TMPrecision1 = time.Unix(1596766024, 123456789)
- tm.TMPrecision2 = time.Unix(1596766024, 123456789)
- _, err := dORM.Insert(tm)
- throwFail(t, err)
-
- err = dORM.QueryTable("tm").One(&recTM)
- throwFail(t, err)
- throwFail(t, AssertIs(recTM.TMPrecision1.String(), "2020-08-07 02:07:04.123 +0000 UTC"))
- throwFail(t, AssertIs(recTM.TMPrecision2.String(), "2020-08-07 02:07:04.1235 +0000 UTC"))
-}
-
func TestNullDataTypes(t *testing.T) {
d := DataNull{}
@@ -481,11 +455,9 @@ func TestNullDataTypes(t *testing.T) {
throwFail(t, AssertIs(*d.Float32Ptr, float32Ptr))
throwFail(t, AssertIs(*d.Float64Ptr, float64Ptr))
throwFail(t, AssertIs(*d.DecimalPtr, decimalPtr))
-
- // in mysql, there are some precision problem, (*d.TimePtr).UTC() != timePtr.UTC()
- assert.True(t, (*d.TimePtr).UTC().Sub(timePtr.UTC()) <= time.Second)
- assert.True(t, (*d.DatePtr).UTC().Sub(datePtr.UTC()) <= time.Second)
- assert.True(t, (*d.DateTimePtr).UTC().Sub(dateTimePtr.UTC()) <= time.Second)
+ throwFail(t, AssertIs((*d.TimePtr).UTC().Format(testTime), timePtr.UTC().Format(testTime)))
+ throwFail(t, AssertIs((*d.DatePtr).UTC().Format(testDate), datePtr.UTC().Format(testDate)))
+ throwFail(t, AssertIs((*d.DateTimePtr).UTC().Format(testDateTime), dateTimePtr.UTC().Format(testDateTime)))
// test support for pointer fields using RawSeter.QueryRows()
var dnList []*DataNull
@@ -560,9 +532,8 @@ func TestCRUD(t *testing.T) {
throwFail(t, AssertIs(u.Status, 3))
throwFail(t, AssertIs(u.IsStaff, true))
throwFail(t, AssertIs(u.IsActive, true))
-
- assert.True(t, u.Created.In(DefaultTimeLoc).Sub(user.Created.In(DefaultTimeLoc)) <= time.Second)
- assert.True(t, u.Updated.In(DefaultTimeLoc).Sub(user.Updated.In(DefaultTimeLoc)) <= time.Second)
+ throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), user.Created.In(DefaultTimeLoc), testDate))
+ throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), user.Updated.In(DefaultTimeLoc), testDateTime))
user.UserName = "astaxie"
user.Profile = profile
@@ -798,20 +769,6 @@ func TestCustomField(t *testing.T) {
throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
-
- var users []User
- Q := dDbBaser.TableQuote()
- n, err := dORM.Raw(fmt.Sprintf("SELECT * FROM %suser%s where id=?", Q, Q), 2).QueryRows(&users)
- throwFailNow(t, err)
- throwFailNow(t, AssertIs(n, 1))
- throwFailNow(t, AssertIs(users[0].Extra.Name, "beego"))
- throwFailNow(t, AssertIs(users[0].Extra.Data, "orm"))
-
- user = User{}
- err = dORM.Raw(fmt.Sprintf("SELECT * FROM %suser%s where id=?", Q, Q), 2).QueryRow(&user)
- throwFailNow(t, err)
- throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
- throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
}
func TestExpr(t *testing.T) {
@@ -833,32 +790,6 @@ func TestExpr(t *testing.T) {
// throwFail(t, AssertIs(num, 3))
}
-func TestSpecifyIndex(t *testing.T) {
- var index *Index
- index = &Index{
- F1: 1,
- F2: 2,
- }
- _, _ = dORM.Insert(index)
- throwFailNow(t, AssertIs(index.Id, 1))
-
- index = &Index{
- F1: 3,
- F2: 4,
- }
- _, _ = dORM.Insert(index)
- throwFailNow(t, AssertIs(index.Id, 2))
-
- _ = dORM.QueryTable(&Index{}).Filter(`f1`, `1`).ForceIndex(`index_f1`).One(index)
- throwFailNow(t, AssertIs(index.F2, 2))
-
- _ = dORM.QueryTable(&Index{}).Filter(`f2`, `4`).UseIndex(`index_f2`).One(index)
- throwFailNow(t, AssertIs(index.F1, 3))
-
- _ = dORM.QueryTable(&Index{}).Filter(`f1`, `1`).IgnoreIndex(`index_f1`, `index_f2`).One(index)
- throwFailNow(t, AssertIs(index.F2, 2))
-}
-
func TestOperators(t *testing.T) {
qs := dORM.QueryTable("user")
num, err := qs.Filter("user_name", "slene").Count()
@@ -877,17 +808,6 @@ func TestOperators(t *testing.T) {
throwFail(t, err)
throwFail(t, AssertIs(num, 1))
- if IsMysql {
- // Now only mysql support `strictexact`
- num, err = qs.Filter("user_name__strictexact", "Slene").Count()
- throwFail(t, err)
- throwFail(t, AssertIs(num, 0))
-
- num, err = qs.Filter("user_name__strictexact", "slene").Count()
- throwFail(t, err)
- throwFail(t, AssertIs(num, 1))
- }
-
num, err = qs.Filter("user_name__contains", "e").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 2))
@@ -1356,32 +1276,24 @@ func TestLoadRelated(t *testing.T) {
throwFailNow(t, AssertIs(len(user.Posts), 2))
throwFailNow(t, AssertIs(user.Posts[0].User.ID, 3))
- num, err = dORM.LoadRelated(&user, "Posts", hints.DefaultRelDepth())
+ num, err = dORM.LoadRelated(&user, "Posts", true)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 2))
throwFailNow(t, AssertIs(len(user.Posts), 2))
throwFailNow(t, AssertIs(user.Posts[0].User.UserName, "astaxie"))
- num, err = dORM.LoadRelated(&user, "Posts",
- hints.DefaultRelDepth(),
- hints.Limit(1))
+ num, err = dORM.LoadRelated(&user, "Posts", true, 1)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 1))
throwFailNow(t, AssertIs(len(user.Posts), 1))
- num, err = dORM.LoadRelated(&user, "Posts",
- hints.DefaultRelDepth(),
- hints.OrderBy("-Id"))
+ num, err = dORM.LoadRelated(&user, "Posts", true, 0, 0, "-Id")
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 2))
throwFailNow(t, AssertIs(len(user.Posts), 2))
throwFailNow(t, AssertIs(user.Posts[0].Title, "Formatting"))
- num, err = dORM.LoadRelated(&user, "Posts",
- hints.DefaultRelDepth(),
- hints.Limit(1),
- hints.Offset(1),
- hints.OrderBy("Id"))
+ num, err = dORM.LoadRelated(&user, "Posts", true, 1, 1, "Id")
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 1))
throwFailNow(t, AssertIs(len(user.Posts), 1))
@@ -1403,7 +1315,7 @@ func TestLoadRelated(t *testing.T) {
throwFailNow(t, AssertIs(profile.User == nil, false))
throwFailNow(t, AssertIs(profile.User.UserName, "astaxie"))
- num, err = dORM.LoadRelated(&profile, "User", hints.DefaultRelDepth())
+ num, err = dORM.LoadRelated(&profile, "User", true)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 1))
throwFailNow(t, AssertIs(profile.User == nil, false))
@@ -1420,7 +1332,7 @@ func TestLoadRelated(t *testing.T) {
throwFailNow(t, AssertIs(user.Profile == nil, false))
throwFailNow(t, AssertIs(user.Profile.Age, 30))
- num, err = dORM.LoadRelated(&user, "Profile", hints.DefaultRelDepth())
+ num, err = dORM.LoadRelated(&user, "Profile", true)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 1))
throwFailNow(t, AssertIs(user.Profile == nil, false))
@@ -1440,7 +1352,7 @@ func TestLoadRelated(t *testing.T) {
throwFailNow(t, AssertIs(post.User == nil, false))
throwFailNow(t, AssertIs(post.User.UserName, "astaxie"))
- num, err = dORM.LoadRelated(&post, "User", hints.DefaultRelDepth())
+ num, err = dORM.LoadRelated(&post, "User", true)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 1))
throwFailNow(t, AssertIs(post.User == nil, false))
@@ -1460,7 +1372,7 @@ func TestLoadRelated(t *testing.T) {
throwFailNow(t, AssertIs(len(post.Tags), 2))
throwFailNow(t, AssertIs(post.Tags[0].Name, "golang"))
- num, err = dORM.LoadRelated(&post, "Tags", hints.DefaultRelDepth())
+ num, err = dORM.LoadRelated(&post, "Tags", true)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 2))
throwFailNow(t, AssertIs(len(post.Tags), 2))
@@ -1481,7 +1393,7 @@ func TestLoadRelated(t *testing.T) {
throwFailNow(t, AssertIs(tag.Posts[0].User.ID, 2))
throwFailNow(t, AssertIs(tag.Posts[0].User.Profile == nil, true))
- num, err = dORM.LoadRelated(&tag, "Posts", hints.DefaultRelDepth())
+ num, err = dORM.LoadRelated(&tag, "Posts", true)
throwFailNow(t, err)
throwFailNow(t, AssertIs(num, 3))
throwFailNow(t, AssertIs(tag.Posts[0].Title, "Introduction"))
@@ -1744,14 +1656,18 @@ func TestRawQueryRow(t *testing.T) {
switch col {
case "id":
throwFail(t, AssertIs(id, 1))
- break
case "time":
+ v = v.(time.Time).In(DefaultTimeLoc)
+ value := dataValues[col].(time.Time).In(DefaultTimeLoc)
+ throwFail(t, AssertIs(v, value, testTime))
case "date":
+ v = v.(time.Time).In(DefaultTimeLoc)
+ value := dataValues[col].(time.Time).In(DefaultTimeLoc)
+ throwFail(t, AssertIs(v, value, testDate))
case "datetime":
v = v.(time.Time).In(DefaultTimeLoc)
value := dataValues[col].(time.Time).In(DefaultTimeLoc)
- assert.True(t, v.(time.Time).Sub(value) <= time.Second)
- break
+ throwFail(t, AssertIs(v, value, testDateTime))
default:
throwFail(t, AssertIs(v, dataValues[col]))
}
@@ -1773,24 +1689,6 @@ func TestRawQueryRow(t *testing.T) {
throwFail(t, AssertIs(*status, 3))
throwFail(t, AssertIs(pid, nil))
- type Embeded struct {
- Email string
- }
- type queryRowNoModelTest struct {
- Id int
- EmbedField Embeded
- }
-
- cols = []string{
- "id", "email",
- }
- var row queryRowNoModelTest
- query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s WHERE id = ?", Q, strings.Join(cols, sep), Q, Q, Q)
- err = dORM.Raw(query, 4).QueryRow(&row)
- throwFail(t, err)
- throwFail(t, AssertIs(row.Id, 4))
- throwFail(t, AssertIs(row.EmbedField.Email, "nobody@gmail.com"))
-
// test for sql.Null* fields
nData := &DataNull{
NullString: sql.NullString{String: "test sql.null", Valid: true},
@@ -1842,13 +1740,16 @@ func TestQueryRows(t *testing.T) {
vu := e.Interface()
switch name {
case "Time":
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
case "Date":
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
case "DateTime":
- assert.True(t, vu.(time.Time).In(DefaultTimeLoc).Sub(value.(time.Time).In(DefaultTimeLoc)) <= time.Second)
- break
- default:
- assert.Equal(t, value, vu)
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
}
+ throwFail(t, AssertIs(vu == value, true), value, vu)
}
var datas2 []Data
@@ -1866,14 +1767,16 @@ func TestQueryRows(t *testing.T) {
vu := e.Interface()
switch name {
case "Time":
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
case "Date":
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
case "DateTime":
- assert.True(t, vu.(time.Time).In(DefaultTimeLoc).Sub(value.(time.Time).In(DefaultTimeLoc)) <= time.Second)
- break
- default:
- assert.Equal(t, value, vu)
+ vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
+ value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
}
-
+ throwFail(t, AssertIs(vu == value, true), value, vu)
}
var ids []int
@@ -1890,7 +1793,7 @@ func TestQueryRows(t *testing.T) {
throwFailNow(t, AssertIs(ids[2], 4))
throwFailNow(t, AssertIs(usernames[2], "nobody"))
- // test query rows by nested struct
+ //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)
@@ -2117,24 +2020,24 @@ func TestTransaction(t *testing.T) {
// this test worked when database support transaction
o := NewOrm()
- to, err := o.Begin()
+ err := o.Begin()
throwFail(t, err)
var names = []string{"1", "2", "3"}
var tag Tag
tag.Name = names[0]
- id, err := to.Insert(&tag)
+ id, err := o.Insert(&tag)
throwFail(t, err)
throwFail(t, AssertIs(id > 0, true))
- num, err := to.QueryTable("tag").Filter("name", "golang").Update(Params{"name": names[1]})
+ num, err := o.QueryTable("tag").Filter("name", "golang").Update(Params{"name": names[1]})
throwFail(t, err)
throwFail(t, AssertIs(num, 1))
switch {
case IsMysql || IsSqlite:
- res, err := to.Raw("INSERT INTO tag (name) VALUES (?)", names[2]).Exec()
+ res, err := o.Raw("INSERT INTO tag (name) VALUES (?)", names[2]).Exec()
throwFail(t, err)
if err == nil {
id, err = res.LastInsertId()
@@ -2143,22 +2046,22 @@ func TestTransaction(t *testing.T) {
}
}
- err = to.Rollback()
+ err = o.Rollback()
throwFail(t, err)
num, err = o.QueryTable("tag").Filter("name__in", names).Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 0))
- to, err = o.Begin()
+ err = o.Begin()
throwFail(t, err)
tag.Name = "commit"
- id, err = to.Insert(&tag)
+ id, err = o.Insert(&tag)
throwFail(t, err)
throwFail(t, AssertIs(id > 0, true))
- to.Commit()
+ o.Commit()
throwFail(t, err)
num, err = o.QueryTable("tag").Filter("name", "commit").Delete()
@@ -2177,33 +2080,33 @@ func TestTransactionIsolationLevel(t *testing.T) {
o2 := NewOrm()
// start two transaction with isolation level repeatable read
- to1, err := o1.BeginWithCtxAndOpts(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
+ err := o1.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
throwFail(t, err)
- to2, err := o2.BeginWithCtxAndOpts(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
+ err = o2.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
throwFail(t, err)
// o1 insert tag
var tag Tag
tag.Name = "test-transaction"
- id, err := to1.Insert(&tag)
+ id, err := o1.Insert(&tag)
throwFail(t, err)
throwFail(t, AssertIs(id > 0, true))
// o2 query tag table, no result
- num, err := to2.QueryTable("tag").Filter("name", "test-transaction").Count()
+ num, err := o2.QueryTable("tag").Filter("name", "test-transaction").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 0))
// o1 commit
- to1.Commit()
+ o1.Commit()
// o2 query tag table, still no result
- num, err = to2.QueryTable("tag").Filter("name", "test-transaction").Count()
+ num, err = o2.QueryTable("tag").Filter("name", "test-transaction").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 0))
// o2 commit and query tag table, get the result
- to2.Commit()
+ o2.Commit()
num, err = o2.QueryTable("tag").Filter("name", "test-transaction").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 1))
@@ -2216,14 +2119,14 @@ func TestTransactionIsolationLevel(t *testing.T) {
func TestBeginTxWithContextCanceled(t *testing.T) {
o := NewOrm()
ctx, cancel := context.WithCancel(context.Background())
- to, _ := o.BeginWithCtx(ctx)
- id, err := to.Insert(&Tag{Name: "test-context"})
+ o.BeginTx(ctx, nil)
+ id, err := o.Insert(&Tag{Name: "test-context"})
throwFail(t, err)
throwFail(t, AssertIs(id > 0, true))
// cancel the context before commit to make it error
cancel()
- err = to.Commit()
+ err = o.Commit()
throwFail(t, AssertIs(err, context.Canceled))
}
@@ -2284,8 +2187,8 @@ func TestInLine(t *testing.T) {
throwFail(t, AssertIs(il.Name, name))
throwFail(t, AssertIs(il.Email, email))
- assert.True(t, il.Created.In(DefaultTimeLoc).Sub(inline.Created.In(DefaultTimeLoc)) <= time.Second)
- assert.True(t, il.Updated.In(DefaultTimeLoc).Sub(inline.Updated.In(DefaultTimeLoc)) <= time.Second)
+ throwFail(t, AssertIs(il.Created.In(DefaultTimeLoc), inline.Created.In(DefaultTimeLoc), testDate))
+ throwFail(t, AssertIs(il.Updated.In(DefaultTimeLoc), inline.Updated.In(DefaultTimeLoc), testDateTime))
}
func TestInLineOneToOne(t *testing.T) {
@@ -2510,7 +2413,7 @@ func TestInsertOrUpdate(t *testing.T) {
fmt.Println("sqlite3 is nonsupport")
return
}
- // test1
+ //test1
_, err := dORM.InsertOrUpdate(&user1, "user_name")
if err != nil {
fmt.Println(err)
@@ -2522,7 +2425,7 @@ func TestInsertOrUpdate(t *testing.T) {
dORM.Read(&test, "user_name")
throwFailNow(t, AssertIs(user1.Status, test.Status))
}
- // test2
+ //test2
_, err = dORM.InsertOrUpdate(&user2, "user_name")
if err != nil {
fmt.Println(err)
@@ -2536,11 +2439,11 @@ func TestInsertOrUpdate(t *testing.T) {
throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password)))
}
- // postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
+ //postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
if IsPostgres {
return
}
- // test3 +
+ //test3 +
_, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status+1")
if err != nil {
fmt.Println(err)
@@ -2552,7 +2455,7 @@ func TestInsertOrUpdate(t *testing.T) {
dORM.Read(&test, "user_name")
throwFailNow(t, AssertIs(user2.Status+1, test.Status))
}
- // test4 -
+ //test4 -
_, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status-1")
if err != nil {
fmt.Println(err)
@@ -2564,7 +2467,7 @@ func TestInsertOrUpdate(t *testing.T) {
dORM.Read(&test, "user_name")
throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status))
}
- // test5 *
+ //test5 *
_, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status*3")
if err != nil {
fmt.Println(err)
@@ -2576,7 +2479,7 @@ func TestInsertOrUpdate(t *testing.T) {
dORM.Read(&test, "user_name")
throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status))
}
- // test6 /
+ //test6 /
_, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3")
if err != nil {
fmt.Println(err)
@@ -2589,82 +2492,3 @@ func TestInsertOrUpdate(t *testing.T) {
throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status))
}
}
-
-func TestStrPkInsert(t *testing.T) {
- RegisterModel(new(StrPk))
- pk := `1`
- value := `StrPkValues(*56`
- strPk := &StrPk{
- Id: pk,
- Value: value,
- }
-
- var err error
- _, err = dORM.Insert(strPk)
- if err != ErrLastInsertIdUnavailable {
- throwFailNow(t, AssertIs(err, nil))
- }
-
- var vForTesting StrPk
- err = dORM.QueryTable(new(StrPk)).Filter(`id`, pk).One(&vForTesting)
- throwFailNow(t, AssertIs(err, nil))
- throwFailNow(t, AssertIs(vForTesting.Value, value))
-
- value2 := `s8s5da7as`
- strPkForUpsert := &StrPk{
- Id: pk,
- Value: value2,
- }
-
- _, err = dORM.InsertOrUpdate(strPkForUpsert, `id`)
- if err != nil {
- fmt.Println(err)
- if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
- } else if err == ErrLastInsertIdUnavailable {
- } else {
- throwFailNow(t, err)
- }
- } else {
- var vForTesting2 StrPk
- err = dORM.QueryTable(new(StrPk)).Filter(`id`, pk).One(&vForTesting2)
- throwFailNow(t, AssertIs(err, nil))
- throwFailNow(t, AssertIs(vForTesting2.Value, value2))
- }
-}
-
-func TestPSQueryBuilder(t *testing.T) {
- // only test postgres
- if dORM.Driver().Type() != 4 {
- return
- }
-
- var user User
- var l []userProfile
- o := NewOrm()
-
- qb, err := NewQueryBuilder("postgres")
- if err != nil {
- throwFailNow(t, err)
- }
- qb.Select("user.id", "user.user_name").
- From("user").Where("id = ?").OrderBy("user_name").
- Desc().Limit(1).Offset(0)
- sql := qb.String()
- err = o.Raw(sql, 2).QueryRow(&user)
- if err != nil {
- throwFailNow(t, err)
- }
- throwFail(t, AssertIs(user.UserName, "slene"))
-
- qb.Select("*").
- From("user_profile").InnerJoin("user").
- On("user_profile.id = user.id")
- sql = qb.String()
- num, err := o.Raw(sql).QueryRows(&l)
- if err != nil {
- throwFailNow(t, err)
- }
- throwFailNow(t, AssertIs(num, 1))
- throwFailNow(t, AssertIs(l[0].UserName, "astaxie"))
- throwFailNow(t, AssertIs(l[0].Age, 30))
-}
diff --git a/client/orm/qb.go b/orm/qb.go
similarity index 96%
rename from client/orm/qb.go
rename to orm/qb.go
index c82d2255..e0655a17 100644
--- a/client/orm/qb.go
+++ b/orm/qb.go
@@ -52,7 +52,7 @@ func NewQueryBuilder(driver string) (qb QueryBuilder, err error) {
} else if driver == "tidb" {
qb = new(TiDBQueryBuilder)
} else if driver == "postgres" {
- qb = new(PostgresQueryBuilder)
+ err = errors.New("postgres query builder is not supported yet")
} else if driver == "sqlite" {
err = errors.New("sqlite query builder is not supported yet")
} else {
diff --git a/client/orm/qb_mysql.go b/orm/qb_mysql.go
similarity index 71%
rename from client/orm/qb_mysql.go
rename to orm/qb_mysql.go
index 19130496..23bdc9ee 100644
--- a/client/orm/qb_mysql.go
+++ b/orm/qb_mysql.go
@@ -25,144 +25,144 @@ const CommaSpace = ", "
// MySQLQueryBuilder is the SQL build
type MySQLQueryBuilder struct {
- tokens []string
+ Tokens []string
}
// Select will join the fields
func (qb *MySQLQueryBuilder) Select(fields ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "SELECT", strings.Join(fields, CommaSpace))
+ qb.Tokens = append(qb.Tokens, "SELECT", strings.Join(fields, CommaSpace))
return qb
}
// ForUpdate add the FOR UPDATE clause
func (qb *MySQLQueryBuilder) ForUpdate() QueryBuilder {
- qb.tokens = append(qb.tokens, "FOR UPDATE")
+ qb.Tokens = append(qb.Tokens, "FOR UPDATE")
return qb
}
// From join the tables
func (qb *MySQLQueryBuilder) From(tables ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "FROM", strings.Join(tables, CommaSpace))
+ qb.Tokens = append(qb.Tokens, "FROM", strings.Join(tables, CommaSpace))
return qb
}
// InnerJoin INNER JOIN the table
func (qb *MySQLQueryBuilder) InnerJoin(table string) QueryBuilder {
- qb.tokens = append(qb.tokens, "INNER JOIN", table)
+ qb.Tokens = append(qb.Tokens, "INNER JOIN", table)
return qb
}
// LeftJoin LEFT JOIN the table
func (qb *MySQLQueryBuilder) LeftJoin(table string) QueryBuilder {
- qb.tokens = append(qb.tokens, "LEFT JOIN", table)
+ qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
return qb
}
// RightJoin RIGHT JOIN the table
func (qb *MySQLQueryBuilder) RightJoin(table string) QueryBuilder {
- qb.tokens = append(qb.tokens, "RIGHT JOIN", table)
+ qb.Tokens = append(qb.Tokens, "RIGHT JOIN", table)
return qb
}
// On join with on cond
func (qb *MySQLQueryBuilder) On(cond string) QueryBuilder {
- qb.tokens = append(qb.tokens, "ON", cond)
+ qb.Tokens = append(qb.Tokens, "ON", cond)
return qb
}
// Where join the Where cond
func (qb *MySQLQueryBuilder) Where(cond string) QueryBuilder {
- qb.tokens = append(qb.tokens, "WHERE", cond)
+ qb.Tokens = append(qb.Tokens, "WHERE", cond)
return qb
}
// And join the and cond
func (qb *MySQLQueryBuilder) And(cond string) QueryBuilder {
- qb.tokens = append(qb.tokens, "AND", cond)
+ qb.Tokens = append(qb.Tokens, "AND", cond)
return qb
}
// Or join the or cond
func (qb *MySQLQueryBuilder) Or(cond string) QueryBuilder {
- qb.tokens = append(qb.tokens, "OR", cond)
+ qb.Tokens = append(qb.Tokens, "OR", cond)
return qb
}
// In join the IN (vals)
func (qb *MySQLQueryBuilder) In(vals ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
+ qb.Tokens = append(qb.Tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
return qb
}
// OrderBy join the Order by fields
func (qb *MySQLQueryBuilder) OrderBy(fields ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "ORDER BY", strings.Join(fields, CommaSpace))
+ qb.Tokens = append(qb.Tokens, "ORDER BY", strings.Join(fields, CommaSpace))
return qb
}
// Asc join the asc
func (qb *MySQLQueryBuilder) Asc() QueryBuilder {
- qb.tokens = append(qb.tokens, "ASC")
+ qb.Tokens = append(qb.Tokens, "ASC")
return qb
}
// Desc join the desc
func (qb *MySQLQueryBuilder) Desc() QueryBuilder {
- qb.tokens = append(qb.tokens, "DESC")
+ qb.Tokens = append(qb.Tokens, "DESC")
return qb
}
// Limit join the limit num
func (qb *MySQLQueryBuilder) Limit(limit int) QueryBuilder {
- qb.tokens = append(qb.tokens, "LIMIT", strconv.Itoa(limit))
+ qb.Tokens = append(qb.Tokens, "LIMIT", strconv.Itoa(limit))
return qb
}
// Offset join the offset num
func (qb *MySQLQueryBuilder) Offset(offset int) QueryBuilder {
- qb.tokens = append(qb.tokens, "OFFSET", strconv.Itoa(offset))
+ qb.Tokens = append(qb.Tokens, "OFFSET", strconv.Itoa(offset))
return qb
}
// GroupBy join the Group by fields
func (qb *MySQLQueryBuilder) GroupBy(fields ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "GROUP BY", strings.Join(fields, CommaSpace))
+ qb.Tokens = append(qb.Tokens, "GROUP BY", strings.Join(fields, CommaSpace))
return qb
}
// Having join the Having cond
func (qb *MySQLQueryBuilder) Having(cond string) QueryBuilder {
- qb.tokens = append(qb.tokens, "HAVING", cond)
+ qb.Tokens = append(qb.Tokens, "HAVING", cond)
return qb
}
// Update join the update table
func (qb *MySQLQueryBuilder) Update(tables ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "UPDATE", strings.Join(tables, CommaSpace))
+ qb.Tokens = append(qb.Tokens, "UPDATE", strings.Join(tables, CommaSpace))
return qb
}
// Set join the set kv
func (qb *MySQLQueryBuilder) Set(kv ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "SET", strings.Join(kv, CommaSpace))
+ qb.Tokens = append(qb.Tokens, "SET", strings.Join(kv, CommaSpace))
return qb
}
// Delete join the Delete tables
func (qb *MySQLQueryBuilder) Delete(tables ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "DELETE")
+ qb.Tokens = append(qb.Tokens, "DELETE")
if len(tables) != 0 {
- qb.tokens = append(qb.tokens, strings.Join(tables, CommaSpace))
+ qb.Tokens = append(qb.Tokens, strings.Join(tables, CommaSpace))
}
return qb
}
// InsertInto join the insert SQL
func (qb *MySQLQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
- qb.tokens = append(qb.tokens, "INSERT INTO", table)
+ qb.Tokens = append(qb.Tokens, "INSERT INTO", table)
if len(fields) != 0 {
fieldsStr := strings.Join(fields, CommaSpace)
- qb.tokens = append(qb.tokens, "(", fieldsStr, ")")
+ qb.Tokens = append(qb.Tokens, "(", fieldsStr, ")")
}
return qb
}
@@ -170,7 +170,7 @@ func (qb *MySQLQueryBuilder) InsertInto(table string, fields ...string) QueryBui
// Values join the Values(vals)
func (qb *MySQLQueryBuilder) Values(vals ...string) QueryBuilder {
valsStr := strings.Join(vals, CommaSpace)
- qb.tokens = append(qb.tokens, "VALUES", "(", valsStr, ")")
+ qb.Tokens = append(qb.Tokens, "VALUES", "(", valsStr, ")")
return qb
}
@@ -179,9 +179,7 @@ func (qb *MySQLQueryBuilder) Subquery(sub string, alias string) string {
return fmt.Sprintf("(%s) AS %s", sub, alias)
}
-// String join all tokens
+// String join all Tokens
func (qb *MySQLQueryBuilder) String() string {
- s := strings.Join(qb.tokens, " ")
- qb.tokens = qb.tokens[:0]
- return s
+ return strings.Join(qb.Tokens, " ")
}
diff --git a/adapter/orm/qb_tidb.go b/orm/qb_tidb.go
similarity index 60%
rename from adapter/orm/qb_tidb.go
rename to orm/qb_tidb.go
index 18631ef0..87b3ae84 100644
--- a/adapter/orm/qb_tidb.go
+++ b/orm/qb_tidb.go
@@ -15,133 +15,168 @@
package orm
import (
- "github.com/astaxie/beego/client/orm"
+ "fmt"
+ "strconv"
+ "strings"
)
// TiDBQueryBuilder is the SQL build
-type TiDBQueryBuilder orm.TiDBQueryBuilder
+type TiDBQueryBuilder struct {
+ Tokens []string
+}
// Select will join the fields
func (qb *TiDBQueryBuilder) Select(fields ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Select(fields...)
+ qb.Tokens = append(qb.Tokens, "SELECT", strings.Join(fields, CommaSpace))
+ return qb
}
// ForUpdate add the FOR UPDATE clause
func (qb *TiDBQueryBuilder) ForUpdate() QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).ForUpdate()
+ qb.Tokens = append(qb.Tokens, "FOR UPDATE")
+ return qb
}
// From join the tables
func (qb *TiDBQueryBuilder) From(tables ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).From(tables...)
+ qb.Tokens = append(qb.Tokens, "FROM", strings.Join(tables, CommaSpace))
+ return qb
}
// InnerJoin INNER JOIN the table
func (qb *TiDBQueryBuilder) InnerJoin(table string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).InnerJoin(table)
+ qb.Tokens = append(qb.Tokens, "INNER JOIN", table)
+ return qb
}
// LeftJoin LEFT JOIN the table
func (qb *TiDBQueryBuilder) LeftJoin(table string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).LeftJoin(table)
+ qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
+ return qb
}
// RightJoin RIGHT JOIN the table
func (qb *TiDBQueryBuilder) RightJoin(table string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).RightJoin(table)
+ qb.Tokens = append(qb.Tokens, "RIGHT JOIN", table)
+ return qb
}
// On join with on cond
func (qb *TiDBQueryBuilder) On(cond string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).On(cond)
+ qb.Tokens = append(qb.Tokens, "ON", cond)
+ return qb
}
// Where join the Where cond
func (qb *TiDBQueryBuilder) Where(cond string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Where(cond)
+ qb.Tokens = append(qb.Tokens, "WHERE", cond)
+ return qb
}
// And join the and cond
func (qb *TiDBQueryBuilder) And(cond string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).And(cond)
+ qb.Tokens = append(qb.Tokens, "AND", cond)
+ return qb
}
// Or join the or cond
func (qb *TiDBQueryBuilder) Or(cond string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Or(cond)
+ qb.Tokens = append(qb.Tokens, "OR", cond)
+ return qb
}
// In join the IN (vals)
func (qb *TiDBQueryBuilder) In(vals ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).In(vals...)
+ qb.Tokens = append(qb.Tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
+ return qb
}
// OrderBy join the Order by fields
func (qb *TiDBQueryBuilder) OrderBy(fields ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).OrderBy(fields...)
+ qb.Tokens = append(qb.Tokens, "ORDER BY", strings.Join(fields, CommaSpace))
+ return qb
}
// Asc join the asc
func (qb *TiDBQueryBuilder) Asc() QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Asc()
+ qb.Tokens = append(qb.Tokens, "ASC")
+ return qb
}
// Desc join the desc
func (qb *TiDBQueryBuilder) Desc() QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Desc()
+ qb.Tokens = append(qb.Tokens, "DESC")
+ return qb
}
// Limit join the limit num
func (qb *TiDBQueryBuilder) Limit(limit int) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Limit(limit)
+ qb.Tokens = append(qb.Tokens, "LIMIT", strconv.Itoa(limit))
+ return qb
}
// Offset join the offset num
func (qb *TiDBQueryBuilder) Offset(offset int) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Offset(offset)
+ qb.Tokens = append(qb.Tokens, "OFFSET", strconv.Itoa(offset))
+ return qb
}
// GroupBy join the Group by fields
func (qb *TiDBQueryBuilder) GroupBy(fields ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).GroupBy(fields...)
+ qb.Tokens = append(qb.Tokens, "GROUP BY", strings.Join(fields, CommaSpace))
+ return qb
}
// Having join the Having cond
func (qb *TiDBQueryBuilder) Having(cond string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Having(cond)
+ qb.Tokens = append(qb.Tokens, "HAVING", cond)
+ return qb
}
// Update join the update table
func (qb *TiDBQueryBuilder) Update(tables ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Update(tables...)
+ qb.Tokens = append(qb.Tokens, "UPDATE", strings.Join(tables, CommaSpace))
+ return qb
}
// Set join the set kv
func (qb *TiDBQueryBuilder) Set(kv ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Set(kv...)
+ qb.Tokens = append(qb.Tokens, "SET", strings.Join(kv, CommaSpace))
+ return qb
}
// Delete join the Delete tables
func (qb *TiDBQueryBuilder) Delete(tables ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Delete(tables...)
+ qb.Tokens = append(qb.Tokens, "DELETE")
+ if len(tables) != 0 {
+ qb.Tokens = append(qb.Tokens, strings.Join(tables, CommaSpace))
+ }
+ return qb
}
// InsertInto join the insert SQL
func (qb *TiDBQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).InsertInto(table, fields...)
+ qb.Tokens = append(qb.Tokens, "INSERT INTO", table)
+ if len(fields) != 0 {
+ fieldsStr := strings.Join(fields, CommaSpace)
+ qb.Tokens = append(qb.Tokens, "(", fieldsStr, ")")
+ }
+ return qb
}
// Values join the Values(vals)
func (qb *TiDBQueryBuilder) Values(vals ...string) QueryBuilder {
- return (*orm.TiDBQueryBuilder)(qb).Values(vals...)
+ valsStr := strings.Join(vals, CommaSpace)
+ qb.Tokens = append(qb.Tokens, "VALUES", "(", valsStr, ")")
+ return qb
}
// Subquery join the sub as alias
func (qb *TiDBQueryBuilder) Subquery(sub string, alias string) string {
- return (*orm.TiDBQueryBuilder)(qb).Subquery(sub, alias)
+ return fmt.Sprintf("(%s) AS %s", sub, alias)
}
// String join all Tokens
func (qb *TiDBQueryBuilder) String() string {
- return (*orm.TiDBQueryBuilder)(qb).String()
+ return strings.Join(qb.Tokens, " ")
}
diff --git a/client/orm/types.go b/orm/types.go
similarity index 77%
rename from client/orm/types.go
rename to orm/types.go
index 34c61d51..2fd10774 100644
--- a/client/orm/types.go
+++ b/orm/types.go
@@ -19,67 +19,8 @@ import (
"database/sql"
"reflect"
"time"
-
- "github.com/astaxie/beego/core/utils"
)
-// TableNaming is usually used by model
-// when you custom your table name, please implement this interfaces
-// for example:
-// type User struct {
-// ...
-// }
-// func (u *User) TableName() string {
-// return "USER_TABLE"
-// }
-type TableNameI interface {
- TableName() string
-}
-
-// TableEngineI is usually used by model
-// when you want to use specific engine, like myisam, you can implement this interface
-// for example:
-// type User struct {
-// ...
-// }
-// func (u *User) TableEngine() string {
-// return "myisam"
-// }
-type TableEngineI interface {
- TableEngine() string
-}
-
-// TableIndexI is usually used by model
-// when you want to create indexes, you can implement this interface
-// for example:
-// type User struct {
-// ...
-// }
-// func (u *User) TableIndex() [][]string {
-// return [][]string{{"Name"}}
-// }
-type TableIndexI interface {
- TableIndex() [][]string
-}
-
-// TableUniqueI is usually used by model
-// when you want to create unique indexes, you can implement this interface
-// for example:
-// type User struct {
-// ...
-// }
-// func (u *User) TableUnique() [][]string {
-// return [][]string{{"Email"}}
-// }
-type TableUniqueI interface {
- TableUnique() [][]string
-}
-
-// IsApplicableTableForDB if return false, we won't create table to this db
-type IsApplicableTableForDB interface {
- IsApplicableTableForDB(db string) bool
-}
-
// Driver define database driver
type Driver interface {
Name() string
@@ -94,43 +35,35 @@ type Fielder interface {
RawValue() interface{}
}
-type TxBeginner interface {
- //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
- 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
- DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
-}
-
-type TxCommitter interface {
- Commit() error
- Rollback() error
-}
-
-//Data Manipulation Language
-type DML interface {
+// Ormer define the orm interface
+type Ormer interface {
+ // 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
+ // Like Read(), but with "FOR UPDATE" clause, useful in transaction.
+ // Some databases are not support this feature.
+ ReadForUpdate(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 be a pointer and Insert will set user's pk field
- Insert(md interface{}) (int64, error)
- InsertWithCtx(ctx context.Context, md interface{}) (int64, error)
+ Insert(interface{}) (int64, error)
// mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value")
// if colu type is integer : can use(+-*/), string : convert(colu,"value")
// postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value")
// if colu type is integer : can use(+-*/), string : colu || "value"
InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error)
- InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error)
// insert some models to database
InsertMulti(bulk int, mds interface{}) (int64, error)
- InsertMultiWithCtx(ctx context.Context, 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
@@ -141,90 +74,61 @@ type DML interface {
// user.Extra.Data = "orm"
// num, err = Ormer.Update(&user, "Langs", "Extra")
Update(md interface{}, cols ...string) (int64, error)
- UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error)
// delete model in database
Delete(md interface{}, cols ...string) (int64, error)
- DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error)
-
- // 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
- RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter
-}
-
-// Data Query Language
-type DQL interface {
- // 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
- ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error
-
- // Like Read(), but with "FOR UPDATE" clause, useful in transaction.
- // Some databases are not support this feature.
- ReadForUpdate(md interface{}, cols ...string) error
- ReadForUpdateWithCtx(ctx context.Context, 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)
- ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, 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{...}
- // hints.DefaultRelDepth useDefaultRelsDepth ; or depth 0
- // hints.RelDepth loadRelationDepth
- // hints.Limit limit default limit 1000
- // hints.Offset int offset default offset 0
- // hints.OrderBy string order for example : "-Id"
+ //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 ...utils.KV) (int64, error)
- LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error)
-
+ 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
- QueryM2MWithCtx(ctx context.Context, 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
- QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter
-
- DBStats() *sql.DBStats
-}
-
-type DriverGetter interface {
+ // 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
+ // begin transaction with provided context and option
+ // the provided context is used until the transaction is committed or rolled back.
+ // if the context is canceled, the transaction will be rolled back.
+ // the provided TxOptions is optional and may be nil if defaults should be used.
+ // if a non-default isolation level is used that the driver doesn't support, an error will be returned.
+ // for example:
+ // o := NewOrm()
+ // err := o.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
+ // ...
+ // err = o.Rollback()
+ BeginTx(ctx context.Context, opts *sql.TxOptions) error
+ // commit transaction
+ Commit() error
+ // rollback transaction
+ Rollback() error
+ // 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
-}
-
-type ormer interface {
- DQL
- DML
- DriverGetter
-}
-
-type Ormer interface {
- ormer
- TxBeginner
-}
-
-type TxOrmer interface {
- ormer
- TxCommitter
+ DBStats() *sql.DBStats
}
// Inserter insert prepared statement
@@ -289,21 +193,6 @@ type QuerySeter interface {
// for example:
// qs.OrderBy("-status")
OrderBy(exprs ...string) QuerySeter
- // add FORCE INDEX expression.
- // for example:
- // qs.ForceIndex(`idx_name1`,`idx_name2`)
- // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive
- ForceIndex(indexes ...string) QuerySeter
- // add USE INDEX expression.
- // for example:
- // qs.UseIndex(`idx_name1`,`idx_name2`)
- // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive
- UseIndex(indexes ...string) QuerySeter
- // add IGNORE INDEX expression.
- // for example:
- // qs.IgnoreIndex(`idx_name1`,`idx_name2`)
- // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive
- IgnoreIndex(indexes ...string) QuerySeter
// set relation model to query together.
// it will query relation models and assign to parent model.
// for example:
@@ -340,7 +229,7 @@ type QuerySeter interface {
// }) // user slene's name will change to slene2
Update(values Params) (int64, error)
// delete from table
- // for example:
+ //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)
@@ -425,8 +314,8 @@ type QueryM2Mer interface {
// 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)
+ //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
@@ -448,10 +337,10 @@ type RawPreparer interface {
// 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
+ //execute sql and get result
Exec() (sql.Result, error)
- // query data and map to container
- // for example:
+ //query data and map to container
+ //for example:
// var name string
// var id int
// rs.QueryRow(&id,&name) // id==2 name=="slene"
@@ -507,11 +396,11 @@ type RawSeter interface {
type stmtQuerier interface {
Close() error
Exec(args ...interface{}) (sql.Result, error)
- // ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error)
+ //ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error)
Query(args ...interface{}) (*sql.Rows, error)
- // QueryContext(args ...interface{}) (*sql.Rows, error)
+ //QueryContext(args ...interface{}) (*sql.Rows, error)
QueryRow(args ...interface{}) *sql.Row
- // QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row
+ //QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row
}
// db querier
@@ -549,27 +438,24 @@ type txEnder interface {
// base database struct
type dbBaser interface {
Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string, bool) error
- ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, *time.Location, []string) (int64, error)
- Count(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
- ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error)
-
Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *alias, ...string) (int64, error)
InsertMulti(dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error)
InsertValue(dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error)
InsertStmt(stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
-
Update(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error)
- UpdateBatch(dbQuerier, *querySet, *modelInfo, *Condition, Params, *time.Location) (int64, error)
-
Delete(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error)
- DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
-
+ ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, *time.Location, []string) (int64, error)
SupportUpdateJoin() bool
+ UpdateBatch(dbQuerier, *querySet, *modelInfo, *Condition, Params, *time.Location) (int64, error)
+ DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
+ Count(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
OperatorSQL(string) string
GenerateOperatorSQL(*modelInfo, *fieldInfo, string, []interface{}, *time.Location) (string, []interface{})
GenerateOperatorLeftCol(*fieldInfo, string, *string)
PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error)
+ ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error)
+ RowsTo(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, string, string, *time.Location) (int64, error)
MaxLimit() uint64
TableQuote() string
ReplaceMarks(*string)
@@ -584,6 +470,4 @@ type dbBaser interface {
IndexExists(dbQuerier, string, string) bool
collectFieldValue(*modelInfo, *fieldInfo, reflect.Value, bool, *time.Location) (interface{}, error)
setval(dbQuerier, *modelInfo, []string) error
-
- GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string
}
diff --git a/client/orm/utils.go b/orm/utils.go
similarity index 100%
rename from client/orm/utils.go
rename to orm/utils.go
diff --git a/adapter/orm/utils_test.go b/orm/utils_test.go
similarity index 100%
rename from adapter/orm/utils_test.go
rename to orm/utils_test.go
diff --git a/server/web/parser.go b/parser.go
similarity index 93%
rename from server/web/parser.go
rename to parser.go
index c3434501..3a311894 100644
--- a/server/web/parser.go
+++ b/parser.go
@@ -12,13 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"encoding/json"
"errors"
"fmt"
"go/ast"
+ "go/parser"
+ "go/token"
"io/ioutil"
"os"
"path/filepath"
@@ -28,19 +30,16 @@ import (
"strings"
"unicode"
- "golang.org/x/tools/go/packages"
-
- "github.com/astaxie/beego/core/logs"
-
- "github.com/astaxie/beego/core/utils"
- "github.com/astaxie/beego/server/web/context/param"
+ "github.com/astaxie/beego/context/param"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/utils"
)
var globalRouterTemplate = `package {{.routersDir}}
import (
- beego "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context/param"{{.globalimport}}
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context/param"{{.globalimport}}
)
func init() {
@@ -77,7 +76,7 @@ func init() {
pkgLastupdate = make(map[string]int64)
}
-func parserPkg(pkgRealpath string) error {
+func parserPkg(pkgRealpath, pkgpath string) error {
rep := strings.NewReplacer("\\", "_", "/", "_", ".", "_")
commentFilename, _ = filepath.Rel(AppPath, pkgRealpath)
commentFilename = commentPrefix + rep.Replace(commentFilename) + ".go"
@@ -86,23 +85,24 @@ func parserPkg(pkgRealpath string) error {
return nil
}
genInfoList = make(map[string][]ControllerComments)
- pkgs, err := packages.Load(&packages.Config{
- Mode: packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedSyntax,
- Dir: pkgRealpath,
- }, "./...")
+ fileSet := token.NewFileSet()
+ astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool {
+ name := info.Name()
+ return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
+ }, parser.ParseComments)
if err != nil {
return err
}
- for _, pkg := range pkgs {
- for _, fl := range pkg.Syntax {
+ for _, pkg := range astPkgs {
+ for _, fl := range pkg.Files {
for _, d := range fl.Decls {
switch specDecl := d.(type) {
case *ast.FuncDecl:
if specDecl.Recv != nil {
exp, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr) // Check that the type is correct first beforing throwing to parser
if ok {
- parserComments(specDecl, fmt.Sprint(exp.X), pkg.PkgPath)
+ parserComments(specDecl, fmt.Sprint(exp.X), pkgpath)
}
}
}
@@ -221,7 +221,7 @@ func buildMethodParams(funcParams []*ast.Field, pc *parsedComment) []*param.Meth
func buildMethodParam(fparam *ast.Field, name string, pc *parsedComment) *param.MethodParam {
options := []param.MethodParamOption{}
if cparam, ok := pc.params[name]; ok {
- // Build param from comment info
+ //Build param from comment info
name = cparam.name
if cparam.required {
options = append(options, param.IsRequired)
@@ -358,10 +358,10 @@ filterLoop:
methods := matches[2]
if methods == "" {
pc.methods = []string{"get"}
- // pc.hasGet = true
+ //pc.hasGet = true
} else {
pc.methods = strings.Split(methods, ",")
- // pc.hasGet = strings.Contains(methods, "get")
+ //pc.hasGet = strings.Contains(methods, "get")
}
pcs = append(pcs, pc)
} else {
@@ -566,17 +566,8 @@ func getpathTime(pkgRealpath string) (lastupdate int64, err error) {
return lastupdate, err
}
for _, f := range fl {
- var t int64
- if f.IsDir() {
- t, err = getpathTime(filepath.Join(pkgRealpath, f.Name()))
- if err != nil {
- return lastupdate, err
- }
- } else {
- t = f.ModTime().UnixNano()
- }
- if lastupdate < t {
- lastupdate = t
+ if lastupdate < f.ModTime().UnixNano() {
+ lastupdate = f.ModTime().UnixNano()
}
}
return lastupdate, nil
diff --git a/server/web/filter/apiauth/apiauth.go b/plugins/apiauth/apiauth.go
similarity index 77%
rename from server/web/filter/apiauth/apiauth.go
rename to plugins/apiauth/apiauth.go
index 58153f1d..10e25f3f 100644
--- a/server/web/filter/apiauth/apiauth.go
+++ b/plugins/apiauth/apiauth.go
@@ -65,15 +65,15 @@ import (
"sort"
"time"
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context"
)
-// AppIDToAppSecret gets appsecret through appid
+// AppIDToAppSecret is used to get appsecret throw appid
type AppIDToAppSecret func(string) string
-// APIBasicAuth uses the basic appid/appkey as the AppIdToAppSecret
-func APIBasicAuth(appid, appkey string) web.FilterFunc {
+// APIBasicAuth use the basic appid/appkey as the AppIdToAppSecret
+func APIBasicAuth(appid, appkey string) beego.FilterFunc {
ft := func(aid string) string {
if aid == appid {
return appkey
@@ -83,53 +83,56 @@ func APIBasicAuth(appid, appkey string) web.FilterFunc {
return APISecretAuth(ft, 300)
}
-// APISecretAuth uses AppIdToAppSecret verify and
-func APISecretAuth(f AppIDToAppSecret, timeout int) web.FilterFunc {
+// APIBaiscAuth calls APIBasicAuth for previous callers
+func APIBaiscAuth(appid, appkey string) beego.FilterFunc {
+ return APIBasicAuth(appid, appkey)
+}
+
+// APISecretAuth use AppIdToAppSecret verify and
+func APISecretAuth(f AppIDToAppSecret, timeout int) beego.FilterFunc {
return func(ctx *context.Context) {
if ctx.Input.Query("appid") == "" {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("missing query parameter: appid")
+ ctx.WriteString("miss query param: appid")
return
}
appsecret := f(ctx.Input.Query("appid"))
if appsecret == "" {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("appid query parameter missing")
+ ctx.WriteString("not exist this appid")
return
}
if ctx.Input.Query("signature") == "" {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("missing query parameter: signature")
-
+ ctx.WriteString("miss query param: signature")
return
}
if ctx.Input.Query("timestamp") == "" {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("missing query parameter: timestamp")
+ ctx.WriteString("miss query param: timestamp")
return
}
u, err := time.Parse("2006-01-02 15:04:05", ctx.Input.Query("timestamp"))
if err != nil {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("incorrect timestamp format. Should be in the form 2006-01-02 15:04:05")
-
+ ctx.WriteString("timestamp format is error, should 2006-01-02 15:04:05")
return
}
t := time.Now()
if t.Sub(u).Seconds() > float64(timeout) {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("request timer timeout exceeded. Please try again")
+ ctx.WriteString("timeout! the request time is long ago, please try again")
return
}
if ctx.Input.Query("signature") !=
Signature(appsecret, ctx.Input.Method(), ctx.Request.Form, ctx.Input.URL()) {
ctx.ResponseWriter.WriteHeader(403)
- ctx.WriteString("authentication failed")
+ ctx.WriteString("auth failed")
}
}
}
-// Signature generates signature with appsecret/method/params/RequestURI
+// Signature used to generate signature with the appsecret/method/params/RequestURI
func Signature(appsecret, method string, params url.Values, RequestURL string) (result string) {
var b bytes.Buffer
keys := make([]string, len(params))
diff --git a/adapter/plugins/apiauth/apiauth_test.go b/plugins/apiauth/apiauth_test.go
similarity index 100%
rename from adapter/plugins/apiauth/apiauth_test.go
rename to plugins/apiauth/apiauth_test.go
diff --git a/server/web/filter/auth/basic.go b/plugins/auth/basic.go
similarity index 94%
rename from server/web/filter/auth/basic.go
rename to plugins/auth/basic.go
index ee6af6c3..c478044a 100644
--- a/server/web/filter/auth/basic.go
+++ b/plugins/auth/basic.go
@@ -40,14 +40,14 @@ import (
"net/http"
"strings"
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context"
)
var defaultRealm = "Authorization Required"
// Basic is the http basic auth
-func Basic(username string, password string) web.FilterFunc {
+func Basic(username string, password string) beego.FilterFunc {
secrets := func(user, pass string) bool {
return user == username && pass == password
}
@@ -55,7 +55,7 @@ func Basic(username string, password string) web.FilterFunc {
}
// NewBasicAuthenticator return the BasicAuth
-func NewBasicAuthenticator(secrets SecretProvider, Realm string) web.FilterFunc {
+func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc {
return func(ctx *context.Context) {
a := &BasicAuth{Secrets: secrets, Realm: Realm}
if username := a.CheckAuth(ctx.Request); username == "" {
diff --git a/server/web/filter/authz/authz.go b/plugins/authz/authz.go
similarity index 94%
rename from server/web/filter/authz/authz.go
rename to plugins/authz/authz.go
index 857c52f2..9dc0db76 100644
--- a/server/web/filter/authz/authz.go
+++ b/plugins/authz/authz.go
@@ -40,17 +40,15 @@
package authz
import (
- "net/http"
-
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context"
"github.com/casbin/casbin"
-
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
+ "net/http"
)
// NewAuthorizer returns the authorizer.
// Use a casbin enforcer as input
-func NewAuthorizer(e *casbin.Enforcer) web.FilterFunc {
+func NewAuthorizer(e *casbin.Enforcer) beego.FilterFunc {
return func(ctx *context.Context) {
a := &BasicAuthorizer{enforcer: e}
diff --git a/adapter/plugins/authz/authz_model.conf b/plugins/authz/authz_model.conf
similarity index 100%
rename from adapter/plugins/authz/authz_model.conf
rename to plugins/authz/authz_model.conf
diff --git a/adapter/plugins/authz/authz_policy.csv b/plugins/authz/authz_policy.csv
similarity index 100%
rename from adapter/plugins/authz/authz_policy.csv
rename to plugins/authz/authz_policy.csv
diff --git a/adapter/plugins/authz/authz_test.go b/plugins/authz/authz_test.go
similarity index 96%
rename from adapter/plugins/authz/authz_test.go
rename to plugins/authz/authz_test.go
index 9b4f21c2..49aed84c 100644
--- a/adapter/plugins/authz/authz_test.go
+++ b/plugins/authz/authz_test.go
@@ -15,14 +15,13 @@
package authz
import (
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context"
+ "github.com/astaxie/beego/plugins/auth"
+ "github.com/casbin/casbin"
"net/http"
"net/http/httptest"
"testing"
-
- beego "github.com/astaxie/beego/adapter"
- "github.com/astaxie/beego/adapter/context"
- "github.com/astaxie/beego/adapter/plugins/auth"
- "github.com/casbin/casbin"
)
func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) {
diff --git a/server/web/filter/cors/cors.go b/plugins/cors/cors.go
similarity index 98%
rename from server/web/filter/cors/cors.go
rename to plugins/cors/cors.go
index 3a6905ea..45c327ab 100644
--- a/server/web/filter/cors/cors.go
+++ b/plugins/cors/cors.go
@@ -42,8 +42,8 @@ import (
"strings"
"time"
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context"
)
const (
@@ -187,7 +187,7 @@ func (o *Options) IsOriginAllowed(origin string) (allowed bool) {
}
// Allow enables CORS for requests those match the provided options.
-func Allow(opts *Options) web.FilterFunc {
+func Allow(opts *Options) beego.FilterFunc {
// Allow default headers if nothing is specified.
if len(opts.AllowHeaders) == 0 {
opts.AllowHeaders = defaultAllowHeaders
diff --git a/server/web/filter/cors/cors_test.go b/plugins/cors/cors_test.go
similarity index 88%
rename from server/web/filter/cors/cors_test.go
rename to plugins/cors/cors_test.go
index 7649de25..34039143 100644
--- a/server/web/filter/cors/cors_test.go
+++ b/plugins/cors/cors_test.go
@@ -21,8 +21,8 @@ import (
"testing"
"time"
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/context"
)
// HTTPHeaderGuardRecorder is httptest.ResponseRecorder with own http.Header
@@ -55,8 +55,8 @@ func (gr *HTTPHeaderGuardRecorder) Header() http.Header {
func Test_AllowAll(t *testing.T) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowAllOrigins: true,
}))
handler.Any("/foo", func(ctx *context.Context) {
@@ -72,8 +72,8 @@ func Test_AllowAll(t *testing.T) {
func Test_AllowRegexMatch(t *testing.T) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowOrigins: []string{"https://aaa.com", "https://*.foo.com"},
}))
handler.Any("/foo", func(ctx *context.Context) {
@@ -92,8 +92,8 @@ func Test_AllowRegexMatch(t *testing.T) {
func Test_AllowRegexNoMatch(t *testing.T) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowOrigins: []string{"https://*.foo.com"},
}))
handler.Any("/foo", func(ctx *context.Context) {
@@ -112,8 +112,8 @@ func Test_AllowRegexNoMatch(t *testing.T) {
func Test_OtherHeaders(t *testing.T) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowAllOrigins: true,
AllowCredentials: true,
AllowMethods: []string{"PATCH", "GET"},
@@ -156,8 +156,8 @@ func Test_OtherHeaders(t *testing.T) {
func Test_DefaultAllowHeaders(t *testing.T) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowAllOrigins: true,
}))
handler.Any("/foo", func(ctx *context.Context) {
@@ -175,8 +175,8 @@ func Test_DefaultAllowHeaders(t *testing.T) {
func Test_Preflight(t *testing.T) {
recorder := NewRecorder()
- handler := web.NewControllerRegister()
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowAllOrigins: true,
AllowMethods: []string{"PUT", "PATCH"},
AllowHeaders: []string{"Origin", "X-whatever", "X-CaseSensitive"},
@@ -219,8 +219,8 @@ func Test_Preflight(t *testing.T) {
func Benchmark_WithoutCORS(b *testing.B) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- web.BConfig.RunMode = web.PROD
+ handler := beego.NewControllerRegister()
+ beego.BConfig.RunMode = beego.PROD
handler.Any("/foo", func(ctx *context.Context) {
ctx.Output.SetStatus(500)
})
@@ -233,9 +233,9 @@ func Benchmark_WithoutCORS(b *testing.B) {
func Benchmark_WithCORS(b *testing.B) {
recorder := httptest.NewRecorder()
- handler := web.NewControllerRegister()
- web.BConfig.RunMode = web.PROD
- handler.InsertFilter("*", web.BeforeRouter, Allow(&Options{
+ handler := beego.NewControllerRegister()
+ beego.BConfig.RunMode = beego.PROD
+ handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowAllOrigins: true,
AllowCredentials: true,
AllowMethods: []string{"PATCH", "GET"},
diff --git a/server/web/policy.go b/policy.go
similarity index 97%
rename from server/web/policy.go
rename to policy.go
index 14673422..ab23f927 100644
--- a/server/web/policy.go
+++ b/policy.go
@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"strings"
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego/context"
)
// PolicyFunc defines a policy function which is invoked before the controller handler is executed.
diff --git a/server/web/router.go b/router.go
similarity index 79%
rename from server/web/router.go
rename to router.go
index 7bb89d82..b19a199d 100644
--- a/server/web/router.go
+++ b/router.go
@@ -12,24 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"errors"
"fmt"
"net/http"
+ "os"
"path"
+ "path/filepath"
"reflect"
"strconv"
"strings"
"sync"
"time"
- "github.com/astaxie/beego/core/logs"
-
- "github.com/astaxie/beego/core/utils"
- beecontext "github.com/astaxie/beego/server/web/context"
- "github.com/astaxie/beego/server/web/context/param"
+ beecontext "github.com/astaxie/beego/context"
+ "github.com/astaxie/beego/context/param"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/toolbox"
+ "github.com/astaxie/beego/utils"
)
// default filter execution points
@@ -132,22 +134,11 @@ type ControllerRegister struct {
enableFilter bool
filters [FinishRouter + 1][]*FilterRouter
pool sync.Pool
-
- // the filter created by FilterChain
- chainRoot *FilterRouter
-
- cfg *Config
}
// NewControllerRegister returns a new ControllerRegister.
-// Usually you should not use this method
-// please use NewControllerRegisterWithCfg
func NewControllerRegister() *ControllerRegister {
- return NewControllerRegisterWithCfg(BeeApp.Cfg)
-}
-
-func NewControllerRegisterWithCfg(cfg *Config) *ControllerRegister {
- res := &ControllerRegister{
+ return &ControllerRegister{
routers: make(map[string]*Tree),
policies: make(map[string]*Tree),
pool: sync.Pool{
@@ -155,10 +146,7 @@ func NewControllerRegisterWithCfg(cfg *Config) *ControllerRegister {
return beecontext.NewContext()
},
},
- cfg: cfg,
}
- res.chainRoot = newFilterRouter("/*", res.serveHttp, WithCaseSensitive(false))
- return res
}
// Add controller handler and pattern rules to ControllerRegister.
@@ -249,7 +237,7 @@ func (p *ControllerRegister) addWithMethodParams(pattern string, c ControllerInt
}
func (p *ControllerRegister) addToRouter(method, pattern string, r *ControllerInfo) {
- if !p.cfg.RouterCaseSensitive {
+ if !BConfig.RouterCaseSensitive {
pattern = strings.ToLower(pattern)
}
if t, ok := p.routers[method]; ok {
@@ -264,6 +252,45 @@ func (p *ControllerRegister) addToRouter(method, pattern string, r *ControllerIn
// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
func (p *ControllerRegister) Include(cList ...ControllerInterface) {
+ if BConfig.RunMode == DEV {
+ skip := make(map[string]bool, 10)
+ wgopath := utils.GetGOPATHs()
+ go111module := os.Getenv(`GO111MODULE`)
+ for _, c := range cList {
+ reflectVal := reflect.ValueOf(c)
+ t := reflect.Indirect(reflectVal).Type()
+ // for go modules
+ if go111module == `on` {
+ pkgpath := filepath.Join(WorkPath, "..", t.PkgPath())
+ if utils.FileExists(pkgpath) {
+ if pkgpath != "" {
+ if _, ok := skip[pkgpath]; !ok {
+ skip[pkgpath] = true
+ parserPkg(pkgpath, t.PkgPath())
+ }
+ }
+ }
+ } else {
+ if len(wgopath) == 0 {
+ panic("you are in dev mode. So please set gopath")
+ }
+ pkgpath := ""
+ for _, wg := range wgopath {
+ wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", t.PkgPath()))
+ if utils.FileExists(wg) {
+ pkgpath = wg
+ break
+ }
+ }
+ if pkgpath != "" {
+ if _, ok := skip[pkgpath]; !ok {
+ skip[pkgpath] = true
+ parserPkg(pkgpath, t.PkgPath())
+ }
+ }
+ }
+ }
+ }
for _, c := range cList {
reflectVal := reflect.ValueOf(c)
t := reflect.Indirect(reflectVal).Type()
@@ -271,7 +298,7 @@ func (p *ControllerRegister) Include(cList ...ControllerInterface) {
if comm, ok := GlobalControllerRouter[key]; ok {
for _, a := range comm {
for _, f := range a.Filters {
- p.InsertFilter(f.Pattern, f.Pos, f.Filter, WithReturnOnOutput(f.ReturnOnOutput), WithResetParams(f.ResetParams))
+ p.InsertFilter(f.Pattern, f.Pos, f.Filter, f.ReturnOnOutput, f.ResetParams)
}
p.addWithMethodParams(a.Router, c, a.MethodParams, strings.Join(a.AllowHTTPMethods, ",")+":"+a.Method)
@@ -461,32 +488,28 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface)
// params is for:
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
// 2. determining whether or not params need to be reset.
-func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) error {
- opts = append(opts, WithCaseSensitive(p.cfg.RouterCaseSensitive))
- mr := newFilterRouter(pattern, filter, opts...)
+func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
+ mr := &FilterRouter{
+ tree: NewTree(),
+ pattern: pattern,
+ filterFunc: filter,
+ returnOnOutput: true,
+ }
+ if !BConfig.RouterCaseSensitive {
+ mr.pattern = strings.ToLower(pattern)
+ }
+
+ paramsLen := len(params)
+ if paramsLen > 0 {
+ mr.returnOnOutput = params[0]
+ }
+ if paramsLen > 1 {
+ mr.resetParams = params[1]
+ }
+ mr.tree.AddRouter(pattern, true)
return p.insertFilterRouter(pos, mr)
}
-// InsertFilterChain is similar to InsertFilter,
-// but it will using chainRoot.filterFunc as input to build a new filterFunc
-// for example, assume that chainRoot is funcA
-// and we add new FilterChain
-// fc := func(next) {
-// return func(ctx) {
-// // do something
-// next(ctx)
-// // do something
-// }
-// }
-func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, opts ...FilterOpt) {
- root := p.chainRoot
- filterFunc := chain(root.filterFunc)
- opts = append(opts, WithCaseSensitive(p.cfg.RouterCaseSensitive))
- p.chainRoot = newFilterRouter(pattern, filterFunc, opts...)
- p.chainRoot.next = root
-
-}
-
// add Filter into
func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) {
if pos < BeforeStatic || pos > FinishRouter {
@@ -645,9 +668,23 @@ func (p *ControllerRegister) getURL(t *Tree, url, controllerName, methodName str
func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, pos int) (started bool) {
var preFilterParams map[string]string
for _, filterR := range p.filters[pos] {
- b, done := filterR.filter(context, urlPath, preFilterParams)
- if done {
- return b
+ if filterR.returnOnOutput && context.ResponseWriter.Started {
+ return true
+ }
+ if filterR.resetParams {
+ preFilterParams = context.Input.Params()
+ }
+ if ok := filterR.ValidRouter(urlPath, context); ok {
+ filterR.filterFunc(context)
+ if filterR.resetParams {
+ context.Input.ResetParams()
+ for k, v := range preFilterParams {
+ context.Input.SetParam(k, v)
+ }
+ }
+ }
+ if filterR.returnOnOutput && context.ResponseWriter.Started {
+ return true
}
}
return false
@@ -655,21 +692,7 @@ func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath str
// Implement http.Handler interface.
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
-
- ctx := p.GetContext()
-
- ctx.Reset(rw, r)
- defer p.GiveBackContext(ctx)
-
- var preFilterParams map[string]string
- p.chainRoot.filter(ctx, p.getUrlPath(ctx), preFilterParams)
-}
-
-func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
- var err error
startTime := time.Now()
- r := ctx.Request
- rw := ctx.ResponseWriter.ResponseWriter
var (
runRouter reflect.Type
findRouter bool
@@ -678,118 +701,102 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
routerInfo *ControllerInfo
isRunnable bool
)
+ context := p.GetContext()
- if p.cfg.RecoverFunc != nil {
- defer p.cfg.RecoverFunc(ctx, p.cfg)
+ context.Reset(rw, r)
+
+ defer p.GiveBackContext(context)
+ if BConfig.RecoverFunc != nil {
+ defer BConfig.RecoverFunc(context)
}
- ctx.Output.EnableGzip = p.cfg.EnableGzip
+ context.Output.EnableGzip = BConfig.EnableGzip
- if p.cfg.RunMode == DEV {
- ctx.Output.Header("Server", p.cfg.ServerName)
+ if BConfig.RunMode == DEV {
+ context.Output.Header("Server", BConfig.ServerName)
}
- urlPath := p.getUrlPath(ctx)
+ var urlPath = r.URL.Path
+
+ if !BConfig.RouterCaseSensitive {
+ urlPath = strings.ToLower(urlPath)
+ }
// filter wrong http method
if !HTTPMETHOD[r.Method] {
- exception("405", ctx)
+ exception("405", context)
goto Admin
}
// filter for static file
- if len(p.filters[BeforeStatic]) > 0 && p.execFilter(ctx, urlPath, BeforeStatic) {
+ if len(p.filters[BeforeStatic]) > 0 && p.execFilter(context, urlPath, BeforeStatic) {
goto Admin
}
- serverStaticRouter(ctx)
+ serverStaticRouter(context)
- if ctx.ResponseWriter.Started {
+ if context.ResponseWriter.Started {
findRouter = true
goto Admin
}
if r.Method != http.MethodGet && r.Method != http.MethodHead {
-
- if ctx.Input.IsUpload() {
- ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
- ctx.Input.Context.Request.Body,
- p.cfg.MaxUploadSize)
- } else if p.cfg.CopyRequestBody {
- // connection will close if the incoming data are larger (RFC 7231, 6.5.11)
- if r.ContentLength > p.cfg.MaxMemory {
- logs.Error(errors.New("payload too large"))
- exception("413", ctx)
- goto Admin
- }
- ctx.Input.CopyBody(p.cfg.MaxMemory)
- } else {
- ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
- ctx.Input.Context.Request.Body,
- p.cfg.MaxMemory)
- }
-
- err = ctx.Input.ParseFormOrMultiForm(p.cfg.MaxMemory)
- if err != nil {
- logs.Error(err)
- if strings.Contains(err.Error(), `http: request body too large`) {
- exception("413", ctx)
- } else {
- exception("500", ctx)
- }
- goto Admin
+ if BConfig.CopyRequestBody && !context.Input.IsUpload() {
+ context.Input.CopyBody(BConfig.MaxMemory)
}
+ context.Input.ParseFormOrMulitForm(BConfig.MaxMemory)
}
// session init
- if p.cfg.WebConfig.Session.SessionOn {
- ctx.Input.CruSession, err = GlobalSessions.SessionStart(rw, r)
+ if BConfig.WebConfig.Session.SessionOn {
+ var err error
+ context.Input.CruSession, err = GlobalSessions.SessionStart(rw, r)
if err != nil {
logs.Error(err)
- exception("503", ctx)
+ exception("503", context)
goto Admin
}
defer func() {
- if ctx.Input.CruSession != nil {
- ctx.Input.CruSession.SessionRelease(nil, rw)
+ if context.Input.CruSession != nil {
+ context.Input.CruSession.SessionRelease(rw)
}
}()
}
- if len(p.filters[BeforeRouter]) > 0 && p.execFilter(ctx, urlPath, BeforeRouter) {
+ if len(p.filters[BeforeRouter]) > 0 && p.execFilter(context, urlPath, BeforeRouter) {
goto Admin
}
// User can define RunController and RunMethod in filter
- if ctx.Input.RunController != nil && ctx.Input.RunMethod != "" {
+ if context.Input.RunController != nil && context.Input.RunMethod != "" {
findRouter = true
- runMethod = ctx.Input.RunMethod
- runRouter = ctx.Input.RunController
+ runMethod = context.Input.RunMethod
+ runRouter = context.Input.RunController
} else {
- routerInfo, findRouter = p.FindRouter(ctx)
+ routerInfo, findRouter = p.FindRouter(context)
}
// if no matches to url, throw a not found exception
if !findRouter {
- exception("404", ctx)
+ exception("404", context)
goto Admin
}
- if splat := ctx.Input.Param(":splat"); splat != "" {
+ if splat := context.Input.Param(":splat"); splat != "" {
for k, v := range strings.Split(splat, "/") {
- ctx.Input.SetParam(strconv.Itoa(k), v)
+ context.Input.SetParam(strconv.Itoa(k), v)
}
}
if routerInfo != nil {
// store router pattern into context
- ctx.Input.SetData("RouterPattern", routerInfo.pattern)
+ context.Input.SetData("RouterPattern", routerInfo.pattern)
}
// execute middleware filters
- if len(p.filters[BeforeExec]) > 0 && p.execFilter(ctx, urlPath, BeforeExec) {
+ if len(p.filters[BeforeExec]) > 0 && p.execFilter(context, urlPath, BeforeExec) {
goto Admin
}
// check policies
- if p.execPolicy(ctx, urlPath) {
+ if p.execPolicy(context, urlPath) {
goto Admin
}
@@ -797,22 +804,22 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
if routerInfo.routerType == routerTypeRESTFul {
if _, ok := routerInfo.methods[r.Method]; ok {
isRunnable = true
- routerInfo.runFunction(ctx)
+ routerInfo.runFunction(context)
} else {
- exception("405", ctx)
+ exception("405", context)
goto Admin
}
} else if routerInfo.routerType == routerTypeHandler {
isRunnable = true
- routerInfo.handler.ServeHTTP(ctx.ResponseWriter, ctx.Request)
+ routerInfo.handler.ServeHTTP(context.ResponseWriter, context.Request)
} else {
runRouter = routerInfo.controllerType
methodParams = routerInfo.methodParams
method := r.Method
- if r.Method == http.MethodPost && ctx.Input.Query("_method") == http.MethodPut {
+ if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodPut {
method = http.MethodPut
}
- if r.Method == http.MethodPost && ctx.Input.Query("_method") == http.MethodDelete {
+ if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodDelete {
method = http.MethodDelete
}
if m, ok := routerInfo.methods[method]; ok {
@@ -841,23 +848,23 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
}
// call the controller init function
- execController.Init(ctx, runRouter.Name(), runMethod, execController)
+ execController.Init(context, runRouter.Name(), runMethod, execController)
// call prepare function
execController.Prepare()
// if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf
- if p.cfg.WebConfig.EnableXSRF {
+ if BConfig.WebConfig.EnableXSRF {
execController.XSRFToken()
if r.Method == http.MethodPost || r.Method == http.MethodDelete || r.Method == http.MethodPut ||
- (r.Method == http.MethodPost && (ctx.Input.Query("_method") == http.MethodDelete || ctx.Input.Query("_method") == http.MethodPut)) {
+ (r.Method == http.MethodPost && (context.Input.Query("_method") == http.MethodDelete || context.Input.Query("_method") == http.MethodPut)) {
execController.CheckXSRFCookie()
}
}
execController.URLMapping()
- if !ctx.ResponseWriter.Started {
+ if !context.ResponseWriter.Started {
// exec main logic
switch runMethod {
case http.MethodGet:
@@ -880,19 +887,19 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
if !execController.HandlerFunc(runMethod) {
vc := reflect.ValueOf(execController)
method := vc.MethodByName(runMethod)
- in := param.ConvertParams(methodParams, method.Type(), ctx)
+ in := param.ConvertParams(methodParams, method.Type(), context)
out := method.Call(in)
// For backward compatibility we only handle response if we had incoming methodParams
if methodParams != nil {
- p.handleParamResponse(ctx, execController, out)
+ p.handleParamResponse(context, execController, out)
}
}
}
// render template
- if !ctx.ResponseWriter.Started && ctx.Output.Status == 0 {
- if p.cfg.WebConfig.AutoRender {
+ if !context.ResponseWriter.Started && context.Output.Status == 0 {
+ if BConfig.WebConfig.AutoRender {
if err := execController.Render(); err != nil {
logs.Error(err)
}
@@ -905,27 +912,27 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
}
// execute middleware filters
- if len(p.filters[AfterExec]) > 0 && p.execFilter(ctx, urlPath, AfterExec) {
+ if len(p.filters[AfterExec]) > 0 && p.execFilter(context, urlPath, AfterExec) {
goto Admin
}
- if len(p.filters[FinishRouter]) > 0 && p.execFilter(ctx, urlPath, FinishRouter) {
+ if len(p.filters[FinishRouter]) > 0 && p.execFilter(context, urlPath, FinishRouter) {
goto Admin
}
Admin:
// admin module record QPS
- statusCode := ctx.ResponseWriter.Status
+ statusCode := context.ResponseWriter.Status
if statusCode == 0 {
statusCode = 200
}
- LogAccess(ctx, &startTime, statusCode)
+ LogAccess(context, &startTime, statusCode)
timeDur := time.Since(startTime)
- ctx.ResponseWriter.Elapsed = timeDur
- if p.cfg.Listen.EnableAdmin {
+ context.ResponseWriter.Elapsed = timeDur
+ if BConfig.Listen.EnableAdmin {
pattern := ""
if routerInfo != nil {
pattern = routerInfo.pattern
@@ -936,14 +943,14 @@ Admin:
if runRouter != nil {
routerName = runRouter.Name()
}
- go StatisticsMap.AddStatistics(r.Method, r.URL.Path, routerName, timeDur)
+ go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, routerName, timeDur)
}
}
- if p.cfg.RunMode == DEV && !p.cfg.Log.AccessLogs {
+ if BConfig.RunMode == DEV && !BConfig.Log.AccessLogs {
match := map[bool]string{true: "match", false: "nomatch"}
devInfo := fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s",
- ctx.Input.IP(),
+ context.Input.IP(),
logs.ColorByStatus(statusCode), statusCode, logs.ResetColor(),
timeDur.String(),
match[findRouter],
@@ -956,19 +963,11 @@ Admin:
logs.Debug(devInfo)
}
// Call WriteHeader if status code has been set changed
- if ctx.Output.Status != 0 {
- ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
+ if context.Output.Status != 0 {
+ context.ResponseWriter.WriteHeader(context.Output.Status)
}
}
-func (p *ControllerRegister) getUrlPath(ctx *beecontext.Context) string {
- urlPath := ctx.Request.URL.Path
- if !p.cfg.RouterCaseSensitive {
- urlPath = strings.ToLower(urlPath)
- }
- return urlPath
-}
-
func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, execController ControllerInterface, results []reflect.Value) {
// looping in reverse order for the case when both error and value are returned and error sets the response status code
for i := len(results) - 1; i >= 0; i-- {
@@ -986,7 +985,7 @@ func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, ex
// FindRouter Find Router info for URL
func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
var urlPath = context.Input.URL()
- if !p.cfg.RouterCaseSensitive {
+ if !BConfig.RouterCaseSensitive {
urlPath = strings.ToLower(urlPath)
}
httpMethod := context.Input.Method()
@@ -1012,5 +1011,36 @@ func toURL(params map[string]string) string {
// LogAccess logging info HTTP Access
func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
- BeeApp.LogAccess(ctx, startTime, statusCode)
+ // Skip logging if AccessLogs config is false
+ if !BConfig.Log.AccessLogs {
+ return
+ }
+ // Skip logging static requests unless EnableStaticLogs config is true
+ if !BConfig.Log.EnableStaticLogs && DefaultAccessLogFilter.Filter(ctx) {
+ return
+ }
+ var (
+ requestTime time.Time
+ elapsedTime time.Duration
+ r = ctx.Request
+ )
+ if startTime != nil {
+ requestTime = *startTime
+ elapsedTime = time.Since(*startTime)
+ }
+ record := &logs.AccessLogRecord{
+ RemoteAddr: ctx.Input.IP(),
+ RequestTime: requestTime,
+ RequestMethod: r.Method,
+ Request: fmt.Sprintf("%s %s %s", r.Method, r.RequestURI, r.Proto),
+ ServerProtocol: r.Proto,
+ Host: r.Host,
+ Status: statusCode,
+ ElapsedTime: elapsedTime,
+ HTTPReferrer: r.Header.Get("Referer"),
+ HTTPUserAgent: r.Header.Get("User-Agent"),
+ RemoteUser: r.Header.Get("Remote-User"),
+ BodyBytesSent: 0, // @todo this one is missing!
+ }
+ logs.AccessLog(record, BConfig.Log.AccessLogsFormat)
}
diff --git a/server/web/router_test.go b/router_test.go
similarity index 88%
rename from server/web/router_test.go
rename to router_test.go
index 59ccd1fc..2797b33a 100644
--- a/server/web/router_test.go
+++ b/router_test.go
@@ -12,18 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
- "bytes"
"net/http"
"net/http/httptest"
"strings"
"testing"
- "github.com/astaxie/beego/core/logs"
-
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego/context"
+ "github.com/astaxie/beego/logs"
)
type TestController struct {
@@ -73,6 +71,7 @@ func (tc *TestController) GetEmptyBody() {
tc.Ctx.Output.Body(res)
}
+
type JSONController struct {
Controller
}
@@ -212,23 +211,6 @@ func TestAutoExtFunc(t *testing.T) {
}
}
-func TestEscape(t *testing.T) {
-
- r, _ := http.NewRequest("GET", "/search/%E4%BD%A0%E5%A5%BD", nil)
- w := httptest.NewRecorder()
-
- handler := NewControllerRegister()
- handler.Get("/search/:keyword(.+)", func(ctx *context.Context) {
- value := ctx.Input.Param(":keyword")
- ctx.Output.Body([]byte(value))
- })
- handler.ServeHTTP(w, r)
- str := w.Body.String()
- if str != "你好" {
- t.Errorf("incorrect, %s", str)
- }
-}
-
func TestRouteOk(t *testing.T) {
r, _ := http.NewRequest("GET", "/person/anderson/thomas?learn=kungfu", nil)
@@ -381,7 +363,7 @@ func TestRouterHandlerAll(t *testing.T) {
}
//
-// Benchmarks NewHttpSever:
+// Benchmarks NewApp:
//
func beegoFilterFunc(ctx *context.Context) {
@@ -440,7 +422,7 @@ func TestInsertFilter(t *testing.T) {
testName := "TestInsertFilter"
mux := NewControllerRegister()
- mux.InsertFilter("*", BeforeRouter, func(*context.Context) {}, WithReturnOnOutput(true))
+ mux.InsertFilter("*", BeforeRouter, func(*context.Context) {})
if !mux.filters[BeforeRouter][0].returnOnOutput {
t.Errorf(
"%s: passing no variadic params should set returnOnOutput to true",
@@ -453,7 +435,7 @@ func TestInsertFilter(t *testing.T) {
}
mux = NewControllerRegister()
- mux.InsertFilter("*", BeforeRouter, func(*context.Context) {}, WithReturnOnOutput(false))
+ mux.InsertFilter("*", BeforeRouter, func(*context.Context) {}, false)
if mux.filters[BeforeRouter][0].returnOnOutput {
t.Errorf(
"%s: passing false as 1st variadic param should set returnOnOutput to false",
@@ -461,7 +443,7 @@ func TestInsertFilter(t *testing.T) {
}
mux = NewControllerRegister()
- mux.InsertFilter("*", BeforeRouter, func(*context.Context) {}, WithReturnOnOutput(true), WithResetParams(true))
+ mux.InsertFilter("*", BeforeRouter, func(*context.Context) {}, true, true)
if !mux.filters[BeforeRouter][0].resetParams {
t.Errorf(
"%s: passing true as 2nd variadic param should set resetParams to true",
@@ -478,7 +460,7 @@ func TestParamResetFilter(t *testing.T) {
mux := NewControllerRegister()
- mux.InsertFilter("*", BeforeExec, beegoResetParams, WithReturnOnOutput(true), WithResetParams(true))
+ mux.InsertFilter("*", BeforeExec, beegoResetParams, true, true)
mux.Get(route, beegoHandleResetParams)
@@ -531,8 +513,8 @@ func TestFilterBeforeExec(t *testing.T) {
url := "/beforeExec"
mux := NewControllerRegister()
- mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput, WithReturnOnOutput(true))
- mux.InsertFilter(url, BeforeExec, beegoBeforeExec1, WithReturnOnOutput(true))
+ mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput)
+ mux.InsertFilter(url, BeforeExec, beegoBeforeExec1)
mux.Get(url, beegoFilterFunc)
@@ -559,7 +541,7 @@ func TestFilterAfterExec(t *testing.T) {
mux := NewControllerRegister()
mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput)
mux.InsertFilter(url, BeforeExec, beegoFilterNoOutput)
- mux.InsertFilter(url, AfterExec, beegoAfterExec1, WithReturnOnOutput(false))
+ mux.InsertFilter(url, AfterExec, beegoAfterExec1, false)
mux.Get(url, beegoFilterFunc)
@@ -587,10 +569,10 @@ func TestFilterFinishRouter(t *testing.T) {
url := "/finishRouter"
mux := NewControllerRegister()
- mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput, WithReturnOnOutput(true))
- mux.InsertFilter(url, BeforeExec, beegoFilterNoOutput, WithReturnOnOutput(true))
- mux.InsertFilter(url, AfterExec, beegoFilterNoOutput, WithReturnOnOutput(true))
- mux.InsertFilter(url, FinishRouter, beegoFinishRouter1, WithReturnOnOutput(true))
+ mux.InsertFilter(url, BeforeRouter, beegoFilterNoOutput)
+ mux.InsertFilter(url, BeforeExec, beegoFilterNoOutput)
+ mux.InsertFilter(url, AfterExec, beegoFilterNoOutput)
+ mux.InsertFilter(url, FinishRouter, beegoFinishRouter1)
mux.Get(url, beegoFilterFunc)
@@ -621,7 +603,7 @@ func TestFilterFinishRouterMultiFirstOnly(t *testing.T) {
url := "/finishRouterMultiFirstOnly"
mux := NewControllerRegister()
- mux.InsertFilter(url, FinishRouter, beegoFinishRouter1, WithReturnOnOutput(false))
+ mux.InsertFilter(url, FinishRouter, beegoFinishRouter1, false)
mux.InsertFilter(url, FinishRouter, beegoFinishRouter2)
mux.Get(url, beegoFilterFunc)
@@ -648,8 +630,8 @@ func TestFilterFinishRouterMulti(t *testing.T) {
url := "/finishRouterMulti"
mux := NewControllerRegister()
- mux.InsertFilter(url, FinishRouter, beegoFinishRouter1, WithReturnOnOutput(false))
- mux.InsertFilter(url, FinishRouter, beegoFinishRouter2, WithReturnOnOutput(false))
+ mux.InsertFilter(url, FinishRouter, beegoFinishRouter1, false)
+ mux.InsertFilter(url, FinishRouter, beegoFinishRouter2, false)
mux.Get(url, beegoFilterFunc)
@@ -674,14 +656,17 @@ func beegoBeforeRouter1(ctx *context.Context) {
ctx.WriteString("|BeforeRouter1")
}
+
func beegoBeforeExec1(ctx *context.Context) {
ctx.WriteString("|BeforeExec1")
}
+
func beegoAfterExec1(ctx *context.Context) {
ctx.WriteString("|AfterExec1")
}
+
func beegoFinishRouter1(ctx *context.Context) {
ctx.WriteString("|FinishRouter1")
}
@@ -724,29 +709,3 @@ func TestYAMLPrepare(t *testing.T) {
t.Errorf(w.Body.String())
}
}
-
-func TestRouterEntityTooLargeCopyBody(t *testing.T) {
- _MaxMemory := BConfig.MaxMemory
- _CopyRequestBody := BConfig.CopyRequestBody
- BConfig.CopyRequestBody = true
- BConfig.MaxMemory = 20
-
- BeeApp.Cfg.CopyRequestBody = true
- BeeApp.Cfg.MaxMemory = 20
- b := bytes.NewBuffer([]byte("barbarbarbarbarbarbarbarbarbar"))
- r, _ := http.NewRequest("POST", "/user/123", b)
- w := httptest.NewRecorder()
-
- handler := NewControllerRegister()
- handler.Post("/user/:id", func(ctx *context.Context) {
- ctx.Output.Body([]byte(ctx.Input.Param(":id")))
- })
- handler.ServeHTTP(w, r)
-
- BConfig.CopyRequestBody = _CopyRequestBody
- BConfig.MaxMemory = _MaxMemory
-
- if w.Code != http.StatusRequestEntityTooLarge {
- t.Errorf("TestRouterRequestEntityTooLarge can't run")
- }
-}
diff --git a/scripts/gobuild.sh b/scripts/gobuild.sh
new file mode 100755
index 00000000..031eafc2
--- /dev/null
+++ b/scripts/gobuild.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+
+# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
+#
+# The original version of this file is located in the https://github.com/istio/common-files repo.
+# If you're looking at this file in a different repo and want to make a change, please go to the
+# common-files repo, make the change there and check it in. Then come back to this repo and run
+# "make update-common".
+
+# Copyright Istio Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This script builds and version stamps the output
+
+# adatp to beego
+
+VERBOSE=${VERBOSE:-"0"}
+V=""
+if [[ "${VERBOSE}" == "1" ]];then
+ V="-x"
+ set -x
+fi
+
+SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+OUT=${1:?"output path"}
+shift
+
+set -e
+
+BUILD_GOOS=${GOOS:-linux}
+BUILD_GOARCH=${GOARCH:-amd64}
+GOBINARY=${GOBINARY:-go}
+GOPKG="$GOPATH/pkg"
+BUILDINFO=${BUILDINFO:-""}
+STATIC=${STATIC:-1}
+LDFLAGS=${LDFLAGS:--extldflags -static}
+GOBUILDFLAGS=${GOBUILDFLAGS:-""}
+# Split GOBUILDFLAGS by spaces into an array called GOBUILDFLAGS_ARRAY.
+IFS=' ' read -r -a GOBUILDFLAGS_ARRAY <<< "$GOBUILDFLAGS"
+
+GCFLAGS=${GCFLAGS:-}
+export CGO_ENABLED=0
+
+if [[ "${STATIC}" != "1" ]];then
+ LDFLAGS=""
+fi
+
+# gather buildinfo if not already provided
+# For a release build BUILDINFO should be produced
+# at the beginning of the build and used throughout
+if [[ -z ${BUILDINFO} ]];then
+ BUILDINFO=$(mktemp)
+ "${SCRIPTPATH}/report_build_info.sh" > "${BUILDINFO}"
+fi
+
+
+# BUILD LD_EXTRAFLAGS
+LD_EXTRAFLAGS=""
+
+while read -r line; do
+ LD_EXTRAFLAGS="${LD_EXTRAFLAGS} -X ${line}"
+done < "${BUILDINFO}"
+
+# verify go version before build
+# NB. this was copied verbatim from Kubernetes hack
+minimum_go_version=go1.13 # supported patterns: go1.x, go1.x.x (x should be a number)
+IFS=" " read -ra go_version <<< "$(${GOBINARY} version)"
+if [[ "${minimum_go_version}" != $(echo -e "${minimum_go_version}\n${go_version[2]}" | sort -s -t. -k 1,1 -k 2,2n -k 3,3n | head -n1) && "${go_version[2]}" != "devel" ]]; then
+ echo "Warning: Detected that you are using an older version of the Go compiler. Beego requires ${minimum_go_version} or greater."
+fi
+
+CURRENT_BRANCH=$(git branch | grep '*')
+CURRENT_BRANCH=${CURRENT_BRANCH:2}
+
+BUILD_TIME=$(date +%Y-%m-%d--%T)
+
+LD_EXTRAFLAGS="${LD_EXTRAFLAGS} -X github.com/astaxie/beego.GoVersion=${go_version[2]:2}"
+LD_EXTRAFLAGS="${LD_EXTRAFLAGS} -X github.com/astaxie/beego.GitBranch=${CURRENT_BRANCH}"
+LD_EXTRAFLAGS="${LD_EXTRAFLAGS} -X github.com/astaxie/beego.BuildTime=$BUILD_TIME"
+
+OPTIMIZATION_FLAGS="-trimpath"
+if [ "${DEBUG}" == "1" ]; then
+ OPTIMIZATION_FLAGS=""
+fi
+
+
+
+echo "BUILD_GOARCH: $BUILD_GOARCH"
+echo "GOPKG: $GOPKG"
+echo "LD_EXTRAFLAGS: $LD_EXTRAFLAGS"
+echo "GO_VERSION: ${go_version[2]}"
+echo "BRANCH: $CURRENT_BRANCH"
+echo "BUILD_TIME: $BUILD_TIME"
+
+time GOOS=${BUILD_GOOS} GOARCH=${BUILD_GOARCH} ${GOBINARY} build \
+ ${V} "${GOBUILDFLAGS_ARRAY[@]}" ${GCFLAGS:+-gcflags "${GCFLAGS}"} \
+ -o "${OUT}" \
+ ${OPTIMIZATION_FLAGS} \
+ -pkgdir="${GOPKG}/${BUILD_GOOS}_${BUILD_GOARCH}" \
+ -ldflags "${LDFLAGS} ${LD_EXTRAFLAGS}" "${@}"
\ No newline at end of file
diff --git a/scripts/report_build_info.sh b/scripts/report_build_info.sh
new file mode 100755
index 00000000..65ba3748
--- /dev/null
+++ b/scripts/report_build_info.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
+#
+# The original version of this file is located in the https://github.com/istio/common-files repo.
+# If you're looking at this file in a different repo and want to make a change, please go to the
+# common-files repo, make the change there and check it in. Then come back to this repo and run
+# "make update-common".
+
+# Copyright Istio Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# adapt to beego
+
+if BUILD_GIT_REVISION=$(git rev-parse HEAD 2> /dev/null); then
+ if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
+ BUILD_GIT_REVISION=${BUILD_GIT_REVISION}"-dirty"
+ fi
+else
+ BUILD_GIT_REVISION=unknown
+fi
+
+# Check for local changes
+if git diff-index --quiet HEAD --; then
+ tree_status="Clean"
+else
+ tree_status="Modified"
+fi
+
+# security wanted VERSION='unknown'
+VERSION="${BUILD_GIT_REVISION}"
+if [[ -n ${BEEGO_VERSION} ]]; then
+ VERSION="${BEEGO_VERSION}"
+fi
+
+GIT_DESCRIBE_TAG=$(git describe --tags)
+
+echo "github.com/astaxie/beego.BuildVersion=${VERSION}"
+echo "github.com/astaxie/beego.BuildGitRevision=${BUILD_GIT_REVISION}"
+echo "github.com/astaxie/beego.BuildStatus=${tree_status}"
+echo "github.com/astaxie/beego.BuildTag=${GIT_DESCRIBE_TAG}"
\ No newline at end of file
diff --git a/server/web/LICENSE b/server/web/LICENSE
deleted file mode 100644
index 5dbd4243..00000000
--- a/server/web/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2014 astaxie
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
\ No newline at end of file
diff --git a/server/web/admin.go b/server/web/admin.go
deleted file mode 100644
index 1b06f486..00000000
--- a/server/web/admin.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "fmt"
- "net/http"
- "reflect"
- "time"
-
- "github.com/astaxie/beego/core/logs"
-)
-
-// BeeAdminApp is the default adminApp used by admin module.
-var beeAdminApp *adminApp
-
-// FilterMonitorFunc is default monitor filter when admin module is enable.
-// if this func returns, admin module records qps for this request by condition of this function logic.
-// usage:
-// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
-// if method == "POST" {
-// return false
-// }
-// if t.Nanoseconds() < 100 {
-// return false
-// }
-// if strings.HasPrefix(requestPath, "/astaxie") {
-// return false
-// }
-// return true
-// }
-// beego.FilterMonitorFunc = MyFilterMonitor.
-var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
-
-func init() {
-
- FilterMonitorFunc = func(string, string, time.Duration, string, int) bool { return true }
-
-}
-
-func list(root string, p interface{}, m M) {
- pt := reflect.TypeOf(p)
- pv := reflect.ValueOf(p)
- if pt.Kind() == reflect.Ptr {
- pt = pt.Elem()
- pv = pv.Elem()
- }
- for i := 0; i < pv.NumField(); i++ {
- var key string
- if root == "" {
- key = pt.Field(i).Name
- } else {
- key = root + "." + pt.Field(i).Name
- }
- if pv.Field(i).Kind() == reflect.Struct {
- list(key, pv.Field(i).Interface(), m)
- } else {
- m[key] = pv.Field(i).Interface()
- }
- }
-}
-
-func writeJSON(rw http.ResponseWriter, jsonData []byte) {
- rw.Header().Set("Content-Type", "application/json")
- rw.Write(jsonData)
-}
-
-// adminApp is an http.HandlerFunc map used as beeAdminApp.
-type adminApp struct {
- *HttpServer
-}
-
-// Route adds http.HandlerFunc to adminApp with url pattern.
-func (admin *adminApp) Run() {
-
- // if len(task.AdminTaskList) > 0 {
- // task.StartTask()
- // }
- logs.Warning("now we don't start tasks here, if you use task module," +
- " please invoke task.StartTask, or task will not be executed")
-
- addr := BConfig.Listen.AdminAddr
-
- if BConfig.Listen.AdminPort != 0 {
- addr = fmt.Sprintf("%s:%d", BConfig.Listen.AdminAddr, BConfig.Listen.AdminPort)
- }
-
- logs.Info("Admin server Running on %s", addr)
-
- admin.HttpServer.Run(addr)
-}
-
-func registerAdmin() error {
- if BConfig.Listen.EnableAdmin {
-
- c := &adminController{
- servers: make([]*HttpServer, 0, 2),
- }
- beeAdminApp = &adminApp{
- HttpServer: NewHttpServerWithCfg(BConfig),
- }
- // keep in mind that all data should be html escaped to avoid XSS attack
- beeAdminApp.Router("/", c, "get:AdminIndex")
- beeAdminApp.Router("/qps", c, "get:QpsIndex")
- beeAdminApp.Router("/prof", c, "get:ProfIndex")
- beeAdminApp.Router("/healthcheck", c, "get:Healthcheck")
- beeAdminApp.Router("/task", c, "get:TaskStatus")
- beeAdminApp.Router("/listconf", c, "get:ListConf")
- beeAdminApp.Router("/metrics", c, "get:PrometheusMetrics")
-
- go beeAdminApp.Run()
- }
- return nil
-}
diff --git a/server/web/admin_controller.go b/server/web/admin_controller.go
deleted file mode 100644
index 2998c8d4..00000000
--- a/server/web/admin_controller.go
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "net/http"
- "strconv"
- "text/template"
-
- "github.com/prometheus/client_golang/prometheus/promhttp"
-
- "github.com/astaxie/beego/core/governor"
-)
-
-type adminController struct {
- Controller
- servers []*HttpServer
-}
-
-func (a *adminController) registerHttpServer(svr *HttpServer) {
- a.servers = append(a.servers, svr)
-}
-
-// ProfIndex is a http.Handler for showing profile command.
-// it's in url pattern "/prof" in admin module.
-func (a *adminController) ProfIndex() {
- rw, r := a.Ctx.ResponseWriter, a.Ctx.Request
- r.ParseForm()
- command := r.Form.Get("command")
- if command == "" {
- return
- }
-
- var (
- format = r.Form.Get("format")
- data = make(map[interface{}]interface{})
- result bytes.Buffer
- )
- governor.ProcessInput(command, &result)
- data["Content"] = template.HTMLEscapeString(result.String())
-
- if format == "json" && command == "gc summary" {
- dataJSON, err := json.Marshal(data)
- if err != nil {
- http.Error(rw, err.Error(), http.StatusInternalServerError)
- return
- }
- writeJSON(rw, dataJSON)
- return
- }
-
- data["Title"] = template.HTMLEscapeString(command)
- defaultTpl := defaultScriptsTpl
- if command == "gc summary" {
- defaultTpl = gcAjaxTpl
- }
- writeTemplate(rw, data, profillingTpl, defaultTpl)
-}
-
-func (a *adminController) PrometheusMetrics() {
- promhttp.Handler().ServeHTTP(a.Ctx.ResponseWriter, a.Ctx.Request)
-}
-
-// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
-// it's in "/task" pattern in admin module.
-func (a *adminController) TaskStatus() {
-
- rw, req := a.Ctx.ResponseWriter, a.Ctx.Request
-
- data := make(map[interface{}]interface{})
-
- // Run Task
- req.ParseForm()
- taskname := req.Form.Get("taskname")
- if taskname != "" {
- cmd := governor.GetCommand("task", "run")
- res := cmd.Execute(taskname)
- if res.IsSuccess() {
-
- data["Message"] = []string{"success",
- template.HTMLEscapeString(fmt.Sprintf("%s run success,Now the Status is %s",
- taskname, res.Content.(string)))}
-
- } else {
- data["Message"] = []string{"error", template.HTMLEscapeString(fmt.Sprintf("%s", res.Error))}
- }
- }
-
- // List Tasks
- content := make(M)
- resultList := governor.GetCommand("task", "list").Execute().Content.([][]string)
- var fields = []string{
- "Task Name",
- "Task Spec",
- "Task Status",
- "Last Time",
- "",
- }
-
- content["Fields"] = fields
- content["Data"] = resultList
- data["Content"] = content
- data["Title"] = "Tasks"
- writeTemplate(rw, data, tasksTpl, defaultScriptsTpl)
-}
-
-func (a *adminController) AdminIndex() {
- // AdminIndex is the default http.Handler for admin module.
- // it matches url pattern "/".
- writeTemplate(a.Ctx.ResponseWriter, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl)
-}
-
-// Healthcheck is a http.Handler calling health checking and showing the result.
-// it's in "/healthcheck" pattern in admin module.
-func (a *adminController) Healthcheck() {
- heathCheck(a.Ctx.ResponseWriter, a.Ctx.Request)
-}
-
-func heathCheck(rw http.ResponseWriter, r *http.Request) {
- var (
- result []string
- data = make(map[interface{}]interface{})
- resultList = new([][]string)
- content = M{
- "Fields": []string{"Name", "Message", "Status"},
- }
- )
-
- for name, h := range governor.AdminCheckList {
- if err := h.Check(); err != nil {
- result = []string{
- "error",
- template.HTMLEscapeString(name),
- template.HTMLEscapeString(err.Error()),
- }
- } else {
- result = []string{
- "success",
- template.HTMLEscapeString(name),
- "OK",
- }
- }
- *resultList = append(*resultList, result)
- }
-
- queryParams := r.URL.Query()
- jsonFlag := queryParams.Get("json")
- shouldReturnJSON, _ := strconv.ParseBool(jsonFlag)
-
- if shouldReturnJSON {
- response := buildHealthCheckResponseList(resultList)
- jsonResponse, err := json.Marshal(response)
-
- if err != nil {
- http.Error(rw, err.Error(), http.StatusInternalServerError)
- } else {
- writeJSON(rw, jsonResponse)
- }
- return
- }
-
- content["Data"] = resultList
- data["Content"] = content
- data["Title"] = "Health Check"
-
- writeTemplate(rw, data, healthCheckTpl, defaultScriptsTpl)
-}
-
-// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
-// it's registered with url pattern "/qps" in admin module.
-func (a *adminController) QpsIndex() {
- data := make(map[interface{}]interface{})
- data["Content"] = StatisticsMap.GetMap()
-
- // do html escape before display path, avoid xss
- if content, ok := (data["Content"]).(M); ok {
- if resultLists, ok := (content["Data"]).([][]string); ok {
- for i := range resultLists {
- if len(resultLists[i]) > 0 {
- resultLists[i][0] = template.HTMLEscapeString(resultLists[i][0])
- }
- }
- }
- }
- writeTemplate(a.Ctx.ResponseWriter, data, qpsTpl, defaultScriptsTpl)
-}
-
-// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
-// it's registered with url pattern "/listconf" in admin module.
-func (a *adminController) ListConf() {
- rw := a.Ctx.ResponseWriter
- r := a.Ctx.Request
- r.ParseForm()
- command := r.Form.Get("command")
- if command == "" {
- rw.Write([]byte("command not support"))
- return
- }
-
- data := make(map[interface{}]interface{})
- switch command {
- case "conf":
- m := make(M)
- list("BConfig", BConfig, m)
- m["appConfigPath"] = template.HTMLEscapeString(appConfigPath)
- m["appConfigProvider"] = template.HTMLEscapeString(appConfigProvider)
- tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
- tmpl = template.Must(tmpl.Parse(configTpl))
- tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
-
- data["Content"] = m
-
- tmpl.Execute(rw, data)
-
- case "router":
- content := BeeApp.PrintTree()
- content["Fields"] = []string{
- "Router Pattern",
- "Methods",
- "Controller",
- }
- data["Content"] = content
- data["Title"] = "Routers"
- writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
- case "filter":
- var (
- content = M{
- "Fields": []string{
- "Router Pattern",
- "Filter Function",
- },
- }
- )
-
- filterTypeData := BeeApp.reportFilter()
-
- filterTypes := make([]string, 0, len(filterTypeData))
- for k, _ := range filterTypeData {
- filterTypes = append(filterTypes, k)
- }
-
- content["Data"] = filterTypeData
- content["Methods"] = filterTypes
-
- data["Content"] = content
- data["Title"] = "Filters"
- writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
- default:
- rw.Write([]byte("command not support"))
- }
-}
-
-func writeTemplate(rw http.ResponseWriter, data map[interface{}]interface{}, tpls ...string) {
- tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
- for _, tpl := range tpls {
- tmpl = template.Must(tmpl.Parse(tpl))
- }
- tmpl.Execute(rw, data)
-}
-
-func buildHealthCheckResponseList(healthCheckResults *[][]string) []map[string]interface{} {
- response := make([]map[string]interface{}, len(*healthCheckResults))
-
- for i, healthCheckResult := range *healthCheckResults {
- currentResultMap := make(map[string]interface{})
-
- currentResultMap["name"] = healthCheckResult[0]
- currentResultMap["message"] = healthCheckResult[1]
- currentResultMap["status"] = healthCheckResult[2]
-
- response[i] = currentResultMap
- }
-
- return response
-
-}
-
-// PrintTree print all routers
-// Deprecated using BeeApp directly
-func PrintTree() M {
- return BeeApp.PrintTree()
-}
diff --git a/server/web/admin_test.go b/server/web/admin_test.go
deleted file mode 100644
index 5ef57323..00000000
--- a/server/web/admin_test.go
+++ /dev/null
@@ -1,249 +0,0 @@
-package web
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/core/governor"
-)
-
-type SampleDatabaseCheck struct {
-}
-
-type SampleCacheCheck struct {
-}
-
-func (dc *SampleDatabaseCheck) Check() error {
- return nil
-}
-
-func (cc *SampleCacheCheck) Check() error {
- return errors.New("no cache detected")
-}
-
-func TestList_01(t *testing.T) {
- m := make(M)
- list("BConfig", BConfig, m)
- t.Log(m)
- om := oldMap()
- for k, v := range om {
- if fmt.Sprint(m[k]) != fmt.Sprint(v) {
- t.Log(k, "old-key", v, "new-key", m[k])
- t.FailNow()
- }
- }
-}
-
-func oldMap() M {
- m := make(M)
- m["BConfig.AppName"] = BConfig.AppName
- m["BConfig.RunMode"] = BConfig.RunMode
- m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive
- m["BConfig.ServerName"] = BConfig.ServerName
- m["BConfig.RecoverPanic"] = BConfig.RecoverPanic
- m["BConfig.CopyRequestBody"] = BConfig.CopyRequestBody
- m["BConfig.EnableGzip"] = BConfig.EnableGzip
- m["BConfig.MaxMemory"] = BConfig.MaxMemory
- m["BConfig.EnableErrorsShow"] = BConfig.EnableErrorsShow
- m["BConfig.Listen.Graceful"] = BConfig.Listen.Graceful
- m["BConfig.Listen.ServerTimeOut"] = BConfig.Listen.ServerTimeOut
- m["BConfig.Listen.ListenTCP4"] = BConfig.Listen.ListenTCP4
- m["BConfig.Listen.EnableHTTP"] = BConfig.Listen.EnableHTTP
- m["BConfig.Listen.HTTPAddr"] = BConfig.Listen.HTTPAddr
- m["BConfig.Listen.HTTPPort"] = BConfig.Listen.HTTPPort
- m["BConfig.Listen.EnableHTTPS"] = BConfig.Listen.EnableHTTPS
- m["BConfig.Listen.HTTPSAddr"] = BConfig.Listen.HTTPSAddr
- m["BConfig.Listen.HTTPSPort"] = BConfig.Listen.HTTPSPort
- m["BConfig.Listen.HTTPSCertFile"] = BConfig.Listen.HTTPSCertFile
- m["BConfig.Listen.HTTPSKeyFile"] = BConfig.Listen.HTTPSKeyFile
- m["BConfig.Listen.EnableAdmin"] = BConfig.Listen.EnableAdmin
- m["BConfig.Listen.AdminAddr"] = BConfig.Listen.AdminAddr
- m["BConfig.Listen.AdminPort"] = BConfig.Listen.AdminPort
- m["BConfig.Listen.EnableFcgi"] = BConfig.Listen.EnableFcgi
- m["BConfig.Listen.EnableStdIo"] = BConfig.Listen.EnableStdIo
- m["BConfig.WebConfig.AutoRender"] = BConfig.WebConfig.AutoRender
- m["BConfig.WebConfig.EnableDocs"] = BConfig.WebConfig.EnableDocs
- m["BConfig.WebConfig.FlashName"] = BConfig.WebConfig.FlashName
- m["BConfig.WebConfig.FlashSeparator"] = BConfig.WebConfig.FlashSeparator
- m["BConfig.WebConfig.DirectoryIndex"] = BConfig.WebConfig.DirectoryIndex
- m["BConfig.WebConfig.StaticDir"] = BConfig.WebConfig.StaticDir
- m["BConfig.WebConfig.StaticExtensionsToGzip"] = BConfig.WebConfig.StaticExtensionsToGzip
- m["BConfig.WebConfig.StaticCacheFileSize"] = BConfig.WebConfig.StaticCacheFileSize
- m["BConfig.WebConfig.StaticCacheFileNum"] = BConfig.WebConfig.StaticCacheFileNum
- m["BConfig.WebConfig.TemplateLeft"] = BConfig.WebConfig.TemplateLeft
- m["BConfig.WebConfig.TemplateRight"] = BConfig.WebConfig.TemplateRight
- m["BConfig.WebConfig.ViewsPath"] = BConfig.WebConfig.ViewsPath
- m["BConfig.WebConfig.EnableXSRF"] = BConfig.WebConfig.EnableXSRF
- m["BConfig.WebConfig.XSRFExpire"] = BConfig.WebConfig.XSRFExpire
- m["BConfig.WebConfig.Session.SessionOn"] = BConfig.WebConfig.Session.SessionOn
- m["BConfig.WebConfig.Session.SessionProvider"] = BConfig.WebConfig.Session.SessionProvider
- m["BConfig.WebConfig.Session.SessionName"] = BConfig.WebConfig.Session.SessionName
- m["BConfig.WebConfig.Session.SessionGCMaxLifetime"] = BConfig.WebConfig.Session.SessionGCMaxLifetime
- m["BConfig.WebConfig.Session.SessionProviderConfig"] = BConfig.WebConfig.Session.SessionProviderConfig
- m["BConfig.WebConfig.Session.SessionCookieLifeTime"] = BConfig.WebConfig.Session.SessionCookieLifeTime
- m["BConfig.WebConfig.Session.SessionAutoSetCookie"] = BConfig.WebConfig.Session.SessionAutoSetCookie
- m["BConfig.WebConfig.Session.SessionDomain"] = BConfig.WebConfig.Session.SessionDomain
- m["BConfig.WebConfig.Session.SessionDisableHTTPOnly"] = BConfig.WebConfig.Session.SessionDisableHTTPOnly
- m["BConfig.Log.AccessLogs"] = BConfig.Log.AccessLogs
- m["BConfig.Log.EnableStaticLogs"] = BConfig.Log.EnableStaticLogs
- m["BConfig.Log.AccessLogsFormat"] = BConfig.Log.AccessLogsFormat
- m["BConfig.Log.FileLineNum"] = BConfig.Log.FileLineNum
- m["BConfig.Log.Outputs"] = BConfig.Log.Outputs
- return m
-}
-
-func TestWriteJSON(t *testing.T) {
- t.Log("Testing the adding of JSON to the response")
-
- w := httptest.NewRecorder()
- originalBody := []int{1, 2, 3}
-
- res, _ := json.Marshal(originalBody)
-
- writeJSON(w, res)
-
- decodedBody := []int{}
- err := json.NewDecoder(w.Body).Decode(&decodedBody)
-
- if err != nil {
- t.Fatal("Could not decode response body into slice.")
- }
-
- for i := range decodedBody {
- if decodedBody[i] != originalBody[i] {
- t.Fatalf("Expected %d but got %d in decoded body slice", originalBody[i], decodedBody[i])
- }
- }
-}
-
-func TestHealthCheckHandlerDefault(t *testing.T) {
- endpointPath := "/healthcheck"
-
- governor.AddHealthCheck("database", &SampleDatabaseCheck{})
- governor.AddHealthCheck("cache", &SampleCacheCheck{})
-
- req, err := http.NewRequest("GET", endpointPath, nil)
- if err != nil {
- t.Fatal(err)
- }
-
- w := httptest.NewRecorder()
-
- handler := http.HandlerFunc(heathCheck)
-
- handler.ServeHTTP(w, req)
-
- if status := w.Code; status != http.StatusOK {
- t.Errorf("handler returned wrong status code: got %v want %v",
- status, http.StatusOK)
- }
- if !strings.Contains(w.Body.String(), "database") {
- t.Errorf("Expected 'database' in generated template.")
- }
-
-}
-
-func TestBuildHealthCheckResponseList(t *testing.T) {
- healthCheckResults := [][]string{
- []string{
- "error",
- "Database",
- "Error occured whie starting the db",
- },
- []string{
- "success",
- "Cache",
- "Cache started successfully",
- },
- }
-
- responseList := buildHealthCheckResponseList(&healthCheckResults)
-
- if len(responseList) != len(healthCheckResults) {
- t.Errorf("invalid response map length: got %d want %d",
- len(responseList), len(healthCheckResults))
- }
-
- responseFields := []string{"name", "message", "status"}
-
- for _, response := range responseList {
- for _, field := range responseFields {
- _, ok := response[field]
- if !ok {
- t.Errorf("expected %s to be in the response %v", field, response)
- }
- }
-
- }
-
-}
-
-func TestHealthCheckHandlerReturnsJSON(t *testing.T) {
-
- governor.AddHealthCheck("database", &SampleDatabaseCheck{})
- governor.AddHealthCheck("cache", &SampleCacheCheck{})
-
- req, err := http.NewRequest("GET", "/healthcheck?json=true", nil)
- if err != nil {
- t.Fatal(err)
- }
-
- w := httptest.NewRecorder()
-
- handler := http.HandlerFunc(heathCheck)
-
- handler.ServeHTTP(w, req)
- if status := w.Code; status != http.StatusOK {
- t.Errorf("handler returned wrong status code: got %v want %v",
- status, http.StatusOK)
- }
-
- decodedResponseBody := []map[string]interface{}{}
- expectedResponseBody := []map[string]interface{}{}
-
- expectedJSONString := []byte(`
- [
- {
- "message":"database",
- "name":"success",
- "status":"OK"
- },
- {
- "message":"cache",
- "name":"error",
- "status":"no cache detected"
- }
- ]
- `)
-
- json.Unmarshal(expectedJSONString, &expectedResponseBody)
-
- json.Unmarshal(w.Body.Bytes(), &decodedResponseBody)
-
- if len(expectedResponseBody) != len(decodedResponseBody) {
- t.Errorf("invalid response map length: got %d want %d",
- len(decodedResponseBody), len(expectedResponseBody))
- }
- assert.Equal(t, len(expectedResponseBody), len(decodedResponseBody))
- assert.Equal(t, 2, len(decodedResponseBody))
-
- var database, cache map[string]interface{}
- if decodedResponseBody[0]["message"] == "database" {
- database = decodedResponseBody[0]
- cache = decodedResponseBody[1]
- } else {
- database = decodedResponseBody[1]
- cache = decodedResponseBody[0]
- }
-
- assert.Equal(t, expectedResponseBody[0], database)
- assert.Equal(t, expectedResponseBody[1], cache)
-
-}
diff --git a/server/web/captcha/LICENSE b/server/web/captcha/LICENSE
deleted file mode 100644
index 0ad73ae0..00000000
--- a/server/web/captcha/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011-2014 Dmitry Chestnykh
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/server/web/captcha/README.md b/server/web/captcha/README.md
deleted file mode 100644
index dbc2026b..00000000
--- a/server/web/captcha/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Captcha
-
-an example for use captcha
-
-```
-package controllers
-
-import (
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/cache"
- "github.com/astaxie/beego/utils/captcha"
-)
-
-var cpt *captcha.Captcha
-
-func init() {
- // use beego cache system store the captcha data
- store := cache.NewMemoryCache()
- cpt = captcha.NewWithFilter("/captcha/", store)
-}
-
-type MainController struct {
- beego.Controller
-}
-
-func (this *MainController) Get() {
- this.TplName = "index.tpl"
-}
-
-func (this *MainController) Post() {
- this.TplName = "index.tpl"
-
- this.Data["Success"] = cpt.VerifyReq(this.Ctx.Request)
-}
-```
-
-template usage
-
-```
-{{.Success}}
-
-```
diff --git a/server/web/context/response.go b/server/web/context/response.go
deleted file mode 100644
index 7bd9a7e8..00000000
--- a/server/web/context/response.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package context
-
-import (
- "net/http"
- "strconv"
-)
-
-const (
- //BadRequest indicates HTTP error 400
- BadRequest StatusCode = http.StatusBadRequest
-
- //NotFound indicates HTTP error 404
- NotFound StatusCode = http.StatusNotFound
-)
-
-// StatusCode sets the HTTP response status code
-type StatusCode int
-
-func (s StatusCode) Error() string {
- return strconv.Itoa(int(s))
-}
-
-// Render sets the HTTP status code
-func (s StatusCode) Render(ctx *Context) {
- ctx.Output.SetStatus(int(s))
-}
diff --git a/server/web/doc.go b/server/web/doc.go
deleted file mode 100644
index a32bc576..00000000
--- a/server/web/doc.go
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
-Package beego provide a MVC framework
-beego: an open-source, high-performance, modular, full-stack web framework
-
-It is used for rapid development of RESTful APIs, web apps and backend services in Go.
-beego is inspired by Tornado, Sinatra and Flask with the added benefit of some Go-specific features such as interfaces and struct embedding.
-
- package main
- import "github.com/astaxie/beego"
-
- func main() {
- beego.Run()
- }
-
-more information: http://beego.me
-*/
-package web
diff --git a/server/web/filter.go b/server/web/filter.go
deleted file mode 100644
index 967de8c9..00000000
--- a/server/web/filter.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "strings"
-
- "github.com/astaxie/beego/server/web/context"
-)
-
-// FilterChain is different from pure FilterFunc
-// when you use this, you must invoke next(ctx) inside the FilterFunc which is returned
-// And all those FilterChain will be invoked before other FilterFunc
-type FilterChain func(next FilterFunc) FilterFunc
-
-// FilterFunc defines a filter function which is invoked before the controller handler is executed.
-type FilterFunc func(ctx *context.Context)
-
-// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
-// It can match the URL against a pattern, and execute a filter function
-// when a request with a matching URL arrives.
-type FilterRouter struct {
- filterFunc FilterFunc
- next *FilterRouter
- tree *Tree
- pattern string
- returnOnOutput bool
- resetParams bool
-}
-
-// params is for:
-// 1. setting the returnOnOutput value (false allows multiple filters to execute)
-// 2. determining whether or not params need to be reset.
-func newFilterRouter(pattern string, filter FilterFunc, opts ...FilterOpt) *FilterRouter {
- mr := &FilterRouter{
- tree: NewTree(),
- pattern: pattern,
- filterFunc: filter,
- }
-
- fos := &filterOpts{
- returnOnOutput: true,
- }
-
- for _, o := range opts {
- o(fos)
- }
-
- if !fos.routerCaseSensitive {
- mr.pattern = strings.ToLower(pattern)
- }
-
- mr.returnOnOutput = fos.returnOnOutput
- mr.resetParams = fos.resetParams
- mr.tree.AddRouter(pattern, true)
- return mr
-}
-
-// filter will check whether we need to execute the filter logic
-// return (started, done)
-func (f *FilterRouter) filter(ctx *context.Context, urlPath string, preFilterParams map[string]string) (bool, bool) {
- if f.returnOnOutput && ctx.ResponseWriter.Started {
- return true, true
- }
- if f.resetParams {
- preFilterParams = ctx.Input.Params()
- }
- if ok := f.ValidRouter(urlPath, ctx); ok {
- f.filterFunc(ctx)
- if f.resetParams {
- ctx.Input.ResetParams()
- for k, v := range preFilterParams {
- ctx.Input.SetParam(k, v)
- }
- }
- } else if f.next != nil {
- return f.next.filter(ctx, urlPath, preFilterParams)
- }
- if f.returnOnOutput && ctx.ResponseWriter.Started {
- return true, true
- }
- return false, false
-}
-
-// ValidRouter checks if the current request is matched by this filter.
-// If the request is matched, the values of the URL parameters defined
-// by the filter pattern are also returned.
-func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
- isOk := f.tree.Match(url, ctx)
- if isOk != nil {
- if b, ok := isOk.(bool); ok {
- return b
- }
- }
- return false
-}
-
-type filterOpts struct {
- returnOnOutput bool
- resetParams bool
- routerCaseSensitive bool
-}
-
-type FilterOpt func(opts *filterOpts)
-
-func WithReturnOnOutput(ret bool) FilterOpt {
- return func(opts *filterOpts) {
- opts.returnOnOutput = ret
- }
-}
-
-func WithResetParams(reset bool) FilterOpt {
- return func(opts *filterOpts) {
- opts.resetParams = reset
- }
-}
-
-func WithCaseSensitive(sensitive bool) FilterOpt {
- return func(opts *filterOpts) {
- opts.routerCaseSensitive = sensitive
- }
-}
diff --git a/server/web/filter/apiauth/apiauth_test.go b/server/web/filter/apiauth/apiauth_test.go
deleted file mode 100644
index 1f56cb0f..00000000
--- a/server/web/filter/apiauth/apiauth_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package apiauth
-
-import (
- "net/url"
- "testing"
-)
-
-func TestSignature(t *testing.T) {
- appsecret := "beego secret"
- method := "GET"
- RequestURL := "http://localhost/test/url"
- params := make(url.Values)
- params.Add("arg1", "hello")
- params.Add("arg2", "beego")
-
- signature := "mFdpvLh48ca4mDVEItE9++AKKQ/IVca7O/ZyyB8hR58="
- if Signature(appsecret, method, params, RequestURL) != signature {
- t.Error("Signature error")
- }
-}
diff --git a/server/web/filter/authz/authz_model.conf b/server/web/filter/authz/authz_model.conf
deleted file mode 100644
index d1b3dbd7..00000000
--- a/server/web/filter/authz/authz_model.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-[request_definition]
-r = sub, obj, act
-
-[policy_definition]
-p = sub, obj, act
-
-[role_definition]
-g = _, _
-
-[policy_effect]
-e = some(where (p.eft == allow))
-
-[matchers]
-m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
\ No newline at end of file
diff --git a/server/web/filter/authz/authz_policy.csv b/server/web/filter/authz/authz_policy.csv
deleted file mode 100644
index c062dd3e..00000000
--- a/server/web/filter/authz/authz_policy.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-p, alice, /dataset1/*, GET
-p, alice, /dataset1/resource1, POST
-p, bob, /dataset2/resource1, *
-p, bob, /dataset2/resource2, GET
-p, bob, /dataset2/folder1/*, POST
-p, dataset1_admin, /dataset1/*, *
-g, cathy, dataset1_admin
\ No newline at end of file
diff --git a/server/web/filter/authz/authz_test.go b/server/web/filter/authz/authz_test.go
deleted file mode 100644
index c0d0dde5..00000000
--- a/server/web/filter/authz/authz_test.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package authz
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/casbin/casbin"
-
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
- "github.com/astaxie/beego/server/web/filter/auth"
-)
-
-func testRequest(t *testing.T, handler *web.ControllerRegister, user string, path string, method string, code int) {
- r, _ := http.NewRequest(method, path, nil)
- r.SetBasicAuth(user, "123")
- w := httptest.NewRecorder()
- handler.ServeHTTP(w, r)
-
- if w.Code != code {
- t.Errorf("%s, %s, %s: %d, supposed to be %d", user, path, method, w.Code, code)
- }
-}
-
-func TestBasic(t *testing.T) {
- handler := web.NewControllerRegister()
-
- handler.InsertFilter("*", web.BeforeRouter, auth.Basic("alice", "123"))
- handler.InsertFilter("*", web.BeforeRouter, NewAuthorizer(casbin.NewEnforcer("authz_model.conf", "authz_policy.csv")))
-
- handler.Any("*", func(ctx *context.Context) {
- ctx.Output.SetStatus(200)
- })
-
- testRequest(t, handler, "alice", "/dataset1/resource1", "GET", 200)
- testRequest(t, handler, "alice", "/dataset1/resource1", "POST", 200)
- testRequest(t, handler, "alice", "/dataset1/resource2", "GET", 200)
- testRequest(t, handler, "alice", "/dataset1/resource2", "POST", 403)
-}
-
-func TestPathWildcard(t *testing.T) {
- handler := web.NewControllerRegister()
-
- handler.InsertFilter("*", web.BeforeRouter, auth.Basic("bob", "123"))
- handler.InsertFilter("*", web.BeforeRouter, NewAuthorizer(casbin.NewEnforcer("authz_model.conf", "authz_policy.csv")))
-
- handler.Any("*", func(ctx *context.Context) {
- ctx.Output.SetStatus(200)
- })
-
- testRequest(t, handler, "bob", "/dataset2/resource1", "GET", 200)
- testRequest(t, handler, "bob", "/dataset2/resource1", "POST", 200)
- testRequest(t, handler, "bob", "/dataset2/resource1", "DELETE", 200)
- testRequest(t, handler, "bob", "/dataset2/resource2", "GET", 200)
- testRequest(t, handler, "bob", "/dataset2/resource2", "POST", 403)
- testRequest(t, handler, "bob", "/dataset2/resource2", "DELETE", 403)
-
- testRequest(t, handler, "bob", "/dataset2/folder1/item1", "GET", 403)
- testRequest(t, handler, "bob", "/dataset2/folder1/item1", "POST", 200)
- testRequest(t, handler, "bob", "/dataset2/folder1/item1", "DELETE", 403)
- testRequest(t, handler, "bob", "/dataset2/folder1/item2", "GET", 403)
- testRequest(t, handler, "bob", "/dataset2/folder1/item2", "POST", 200)
- testRequest(t, handler, "bob", "/dataset2/folder1/item2", "DELETE", 403)
-}
-
-func TestRBAC(t *testing.T) {
- handler := web.NewControllerRegister()
-
- handler.InsertFilter("*", web.BeforeRouter, auth.Basic("cathy", "123"))
- e := casbin.NewEnforcer("authz_model.conf", "authz_policy.csv")
- handler.InsertFilter("*", web.BeforeRouter, NewAuthorizer(e))
-
- handler.Any("*", func(ctx *context.Context) {
- ctx.Output.SetStatus(200)
- })
-
- // cathy can access all /dataset1/* resources via all methods because it has the dataset1_admin role.
- testRequest(t, handler, "cathy", "/dataset1/item", "GET", 200)
- testRequest(t, handler, "cathy", "/dataset1/item", "POST", 200)
- testRequest(t, handler, "cathy", "/dataset1/item", "DELETE", 200)
- testRequest(t, handler, "cathy", "/dataset2/item", "GET", 403)
- testRequest(t, handler, "cathy", "/dataset2/item", "POST", 403)
- testRequest(t, handler, "cathy", "/dataset2/item", "DELETE", 403)
-
- // delete all roles on user cathy, so cathy cannot access any resources now.
- e.DeleteRolesForUser("cathy")
-
- testRequest(t, handler, "cathy", "/dataset1/item", "GET", 403)
- testRequest(t, handler, "cathy", "/dataset1/item", "POST", 403)
- testRequest(t, handler, "cathy", "/dataset1/item", "DELETE", 403)
- testRequest(t, handler, "cathy", "/dataset2/item", "GET", 403)
- testRequest(t, handler, "cathy", "/dataset2/item", "POST", 403)
- testRequest(t, handler, "cathy", "/dataset2/item", "DELETE", 403)
-}
diff --git a/server/web/filter/opentracing/filter.go b/server/web/filter/opentracing/filter.go
deleted file mode 100644
index c2defa18..00000000
--- a/server/web/filter/opentracing/filter.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2020 beego
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package opentracing
-
-import (
- "context"
-
- "github.com/astaxie/beego/server/web"
- beegoCtx "github.com/astaxie/beego/server/web/context"
- logKit "github.com/go-kit/kit/log"
- opentracingKit "github.com/go-kit/kit/tracing/opentracing"
- "github.com/opentracing/opentracing-go"
-)
-
-// FilterChainBuilder provides an extension point that we can support more configurations if necessary
-type FilterChainBuilder struct {
- // CustomSpanFunc makes users to custom the span.
- CustomSpanFunc func(span opentracing.Span, ctx *beegoCtx.Context)
-}
-
-func (builder *FilterChainBuilder) FilterChain(next web.FilterFunc) web.FilterFunc {
- return func(ctx *beegoCtx.Context) {
- var (
- spanCtx context.Context
- span opentracing.Span
- )
- operationName := builder.operationName(ctx)
-
- if preSpan := opentracing.SpanFromContext(ctx.Request.Context()); preSpan == nil {
- inject := opentracingKit.HTTPToContext(opentracing.GlobalTracer(), operationName, logKit.NewNopLogger())
- spanCtx = inject(ctx.Request.Context(), ctx.Request)
- span = opentracing.SpanFromContext(spanCtx)
- } else {
- span, spanCtx = opentracing.StartSpanFromContext(ctx.Request.Context(), operationName)
- }
-
- defer span.Finish()
-
- newReq := ctx.Request.Clone(spanCtx)
- ctx.Reset(ctx.ResponseWriter.ResponseWriter, newReq)
-
- next(ctx)
- // if you think we need to do more things, feel free to create an issue to tell us
- span.SetTag("http.status_code", ctx.ResponseWriter.Status)
- span.SetTag("http.method", ctx.Input.Method())
- span.SetTag("peer.hostname", ctx.Request.Host)
- span.SetTag("http.url", ctx.Request.URL.String())
- span.SetTag("http.scheme", ctx.Request.URL.Scheme)
- span.SetTag("span.kind", "server")
- span.SetTag("component", "beego")
- if ctx.Output.IsServerError() || ctx.Output.IsClientError() {
- span.SetTag("error", true)
- }
- span.SetTag("peer.address", ctx.Request.RemoteAddr)
- span.SetTag("http.proto", ctx.Request.Proto)
-
- span.SetTag("beego.route", ctx.Input.GetData("RouterPattern"))
-
- if builder.CustomSpanFunc != nil {
- builder.CustomSpanFunc(span, ctx)
- }
- }
-}
-
-func (builder *FilterChainBuilder) operationName(ctx *beegoCtx.Context) string {
- operationName := ctx.Input.URL()
- // it means that there is not any span, so we create a span as the root span.
- // TODO, if we support multiple servers, this need to be changed
- route, found := web.BeeApp.Handlers.FindRouter(ctx)
- if found {
- operationName = ctx.Input.Method() + "#" + route.GetPattern()
- }
- return operationName
-}
diff --git a/server/web/filter/opentracing/filter_test.go b/server/web/filter/opentracing/filter_test.go
deleted file mode 100644
index d7222c37..00000000
--- a/server/web/filter/opentracing/filter_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2020 beego
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package opentracing
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/opentracing/opentracing-go"
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/server/web/context"
-)
-
-func TestFilterChainBuilder_FilterChain(t *testing.T) {
- builder := &FilterChainBuilder{
- CustomSpanFunc: func(span opentracing.Span, ctx *context.Context) {
- span.SetTag("aa", "bbb")
- },
- }
-
- ctx := context.NewContext()
- r, _ := http.NewRequest("GET", "/prometheus/user", nil)
- w := httptest.NewRecorder()
- ctx.Reset(w, r)
- ctx.Input.SetData("RouterPattern", "my-route")
-
- filterFunc := builder.FilterChain(func(ctx *context.Context) {
- ctx.Input.SetData("opentracing", true)
- })
-
- filterFunc(ctx)
- assert.True(t, ctx.Input.GetData("opentracing").(bool))
-}
diff --git a/server/web/filter/prometheus/filter.go b/server/web/filter/prometheus/filter.go
deleted file mode 100644
index 7daabd5a..00000000
--- a/server/web/filter/prometheus/filter.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2020 beego
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "strconv"
- "strings"
- "time"
-
- "github.com/prometheus/client_golang/prometheus"
-
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/server/web"
- "github.com/astaxie/beego/server/web/context"
-)
-
-// FilterChainBuilder is an extension point,
-// when we want to support some configuration,
-// please use this structure
-type FilterChainBuilder struct {
-}
-
-// FilterChain returns a FilterFunc. The filter will records some metrics
-func (builder *FilterChainBuilder) FilterChain(next web.FilterFunc) web.FilterFunc {
- summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
- Name: "beego",
- Subsystem: "http_request",
- ConstLabels: map[string]string{
- "server": web.BConfig.ServerName,
- "env": web.BConfig.RunMode,
- "appname": web.BConfig.AppName,
- },
- Help: "The statics info for http request",
- }, []string{"pattern", "method", "status", "duration"})
-
- prometheus.MustRegister(summaryVec)
-
- registerBuildInfo()
-
- return func(ctx *context.Context) {
- startTime := time.Now()
- next(ctx)
- endTime := time.Now()
- go report(endTime.Sub(startTime), ctx, summaryVec)
- }
-}
-
-func registerBuildInfo() {
- buildInfo := prometheus.NewGaugeVec(prometheus.GaugeOpts{
- Name: "beego",
- Subsystem: "build_info",
- Help: "The building information",
- ConstLabels: map[string]string{
- "appname": web.BConfig.AppName,
- "build_version": beego.BuildVersion,
- "build_revision": beego.BuildGitRevision,
- "build_status": beego.BuildStatus,
- "build_tag": beego.BuildTag,
- "build_time": strings.Replace(beego.BuildTime, "--", " ", 1),
- "go_version": beego.GoVersion,
- "git_branch": beego.GitBranch,
- "start_time": time.Now().Format("2006-01-02 15:04:05"),
- },
- }, []string{})
-
- prometheus.MustRegister(buildInfo)
- buildInfo.WithLabelValues().Set(1)
-}
-
-func report(dur time.Duration, ctx *context.Context, vec *prometheus.SummaryVec) {
- status := ctx.Output.Status
- ptn := ctx.Input.GetData("RouterPattern").(string)
- ms := dur / time.Millisecond
- vec.WithLabelValues(ptn, ctx.Input.Method(), strconv.Itoa(status), strconv.Itoa(int(ms))).Observe(float64(ms))
-}
diff --git a/server/web/filter/prometheus/filter_test.go b/server/web/filter/prometheus/filter_test.go
deleted file mode 100644
index cb133a64..00000000
--- a/server/web/filter/prometheus/filter_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2020 beego
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/server/web/context"
-)
-
-func TestFilterChain(t *testing.T) {
- filter := (&FilterChainBuilder{}).FilterChain(func(ctx *context.Context) {
- // do nothing
- ctx.Input.SetData("invocation", true)
- })
-
- ctx := context.NewContext()
- r, _ := http.NewRequest("GET", "/prometheus/user", nil)
- w := httptest.NewRecorder()
- ctx.Reset(w, r)
- ctx.Input.SetData("RouterPattern", "my-route")
- filter(ctx)
- assert.True(t, ctx.Input.GetData("invocation").(bool))
-}
diff --git a/server/web/filter_chain_test.go b/server/web/filter_chain_test.go
deleted file mode 100644
index e175ab29..00000000
--- a/server/web/filter_chain_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/server/web/context"
-)
-
-func TestControllerRegister_InsertFilterChain(t *testing.T) {
-
- InsertFilterChain("/*", func(next FilterFunc) FilterFunc {
- return func(ctx *context.Context) {
- ctx.Output.Header("filter", "filter-chain")
- next(ctx)
- }
- })
-
- ns := NewNamespace("/chain")
-
- ns.Get("/*", func(ctx *context.Context) {
- ctx.Output.Body([]byte("hello"))
- })
-
- r, _ := http.NewRequest("GET", "/chain/user", nil)
- w := httptest.NewRecorder()
-
- BeeApp.Handlers.ServeHTTP(w, r)
-
- assert.Equal(t, "filter-chain", w.Header().Get("filter"))
-}
diff --git a/server/web/server.go b/server/web/server.go
deleted file mode 100644
index 25841563..00000000
--- a/server/web/server.go
+++ /dev/null
@@ -1,751 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "crypto/tls"
- "crypto/x509"
- "fmt"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/fcgi"
- "os"
- "path"
- "strconv"
- "strings"
- "text/template"
- "time"
-
- "golang.org/x/crypto/acme/autocert"
-
- "github.com/astaxie/beego/core/logs"
- beecontext "github.com/astaxie/beego/server/web/context"
-
- "github.com/astaxie/beego/core/utils"
- "github.com/astaxie/beego/server/web/grace"
-)
-
-var (
- // BeeApp is an application instance
- // If you are using single server, you could use this
- // But if you need multiple servers, do not use this
- BeeApp *HttpServer
-)
-
-func init() {
- // create beego application
- BeeApp = NewHttpSever()
-}
-
-// HttpServer defines beego application with a new PatternServeMux.
-type HttpServer struct {
- Handlers *ControllerRegister
- Server *http.Server
- Cfg *Config
-}
-
-// NewHttpSever returns a new beego application.
-// this method will use the BConfig as the configure to create HttpServer
-// Be careful that when you update BConfig, the server's Cfg will be updated too
-func NewHttpSever() *HttpServer {
- return NewHttpServerWithCfg(BConfig)
-}
-
-// NewHttpServerWithCfg will create an sever with specific cfg
-func NewHttpServerWithCfg(cfg *Config) *HttpServer {
- cr := NewControllerRegisterWithCfg(cfg)
- app := &HttpServer{
- Handlers: cr,
- Server: &http.Server{},
- Cfg: cfg,
- }
-
- return app
-}
-
-// MiddleWare function for http.Handler
-type MiddleWare func(http.Handler) http.Handler
-
-// Run beego application.
-func (app *HttpServer) Run(addr string, mws ...MiddleWare) {
-
- initBeforeHTTPRun()
-
- app.initAddr(addr)
-
- addr = app.Cfg.Listen.HTTPAddr
-
- if app.Cfg.Listen.HTTPPort != 0 {
- addr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPAddr, app.Cfg.Listen.HTTPPort)
- }
-
- var (
- err error
- l net.Listener
- endRunning = make(chan bool, 1)
- )
-
- // run cgi server
- if app.Cfg.Listen.EnableFcgi {
- if app.Cfg.Listen.EnableStdIo {
- if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O
- logs.Info("Use FCGI via standard I/O")
- } else {
- logs.Critical("Cannot use FCGI via standard I/O", err)
- }
- return
- }
- if app.Cfg.Listen.HTTPPort == 0 {
- // remove the Socket file before start
- if utils.FileExists(addr) {
- os.Remove(addr)
- }
- l, err = net.Listen("unix", addr)
- } else {
- l, err = net.Listen("tcp", addr)
- }
- if err != nil {
- logs.Critical("Listen: ", err)
- }
- if err = fcgi.Serve(l, app.Handlers); err != nil {
- logs.Critical("fcgi.Serve: ", err)
- }
- return
- }
-
- app.Server.Handler = app.Handlers
- for i := len(mws) - 1; i >= 0; i-- {
- if mws[i] == nil {
- continue
- }
- app.Server.Handler = mws[i](app.Server.Handler)
- }
- app.Server.ReadTimeout = time.Duration(app.Cfg.Listen.ServerTimeOut) * time.Second
- app.Server.WriteTimeout = time.Duration(app.Cfg.Listen.ServerTimeOut) * time.Second
- app.Server.ErrorLog = logs.GetLogger("HTTP")
-
- // run graceful mode
- if app.Cfg.Listen.Graceful {
- httpsAddr := app.Cfg.Listen.HTTPSAddr
- app.Server.Addr = httpsAddr
- if app.Cfg.Listen.EnableHTTPS || app.Cfg.Listen.EnableMutualHTTPS {
- go func() {
- time.Sleep(1000 * time.Microsecond)
- if app.Cfg.Listen.HTTPSPort != 0 {
- httpsAddr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPSAddr, app.Cfg.Listen.HTTPSPort)
- app.Server.Addr = httpsAddr
- }
- server := grace.NewServer(httpsAddr, app.Server.Handler)
- server.Server.ReadTimeout = app.Server.ReadTimeout
- server.Server.WriteTimeout = app.Server.WriteTimeout
- if app.Cfg.Listen.EnableMutualHTTPS {
- if err := server.ListenAndServeMutualTLS(app.Cfg.Listen.HTTPSCertFile,
- app.Cfg.Listen.HTTPSKeyFile,
- app.Cfg.Listen.TrustCaFile); err != nil {
- logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
- time.Sleep(100 * time.Microsecond)
- }
- } else {
- if app.Cfg.Listen.AutoTLS {
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist(app.Cfg.Listen.Domains...),
- Cache: autocert.DirCache(app.Cfg.Listen.TLSCacheDir),
- }
- app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
- app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile = "", ""
- }
- if err := server.ListenAndServeTLS(app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile); err != nil {
- logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
- time.Sleep(100 * time.Microsecond)
- }
- }
- endRunning <- true
- }()
- }
- if app.Cfg.Listen.EnableHTTP {
- go func() {
- server := grace.NewServer(addr, app.Server.Handler)
- server.Server.ReadTimeout = app.Server.ReadTimeout
- server.Server.WriteTimeout = app.Server.WriteTimeout
- if app.Cfg.Listen.ListenTCP4 {
- server.Network = "tcp4"
- }
- if err := server.ListenAndServe(); err != nil {
- logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
- time.Sleep(100 * time.Microsecond)
- }
- endRunning <- true
- }()
- }
- <-endRunning
- return
- }
-
- // run normal mode
- if app.Cfg.Listen.EnableHTTPS || app.Cfg.Listen.EnableMutualHTTPS {
- go func() {
- time.Sleep(1000 * time.Microsecond)
- if app.Cfg.Listen.HTTPSPort != 0 {
- app.Server.Addr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPSAddr, app.Cfg.Listen.HTTPSPort)
- } else if app.Cfg.Listen.EnableHTTP {
- logs.Info("Start https server error, conflict with http. Please reset https port")
- return
- }
- logs.Info("https server Running on https://%s", app.Server.Addr)
- if app.Cfg.Listen.AutoTLS {
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist(app.Cfg.Listen.Domains...),
- Cache: autocert.DirCache(app.Cfg.Listen.TLSCacheDir),
- }
- app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
- app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile = "", ""
- } else if app.Cfg.Listen.EnableMutualHTTPS {
- pool := x509.NewCertPool()
- data, err := ioutil.ReadFile(app.Cfg.Listen.TrustCaFile)
- if err != nil {
- logs.Info("MutualHTTPS should provide TrustCaFile")
- return
- }
- pool.AppendCertsFromPEM(data)
- app.Server.TLSConfig = &tls.Config{
- ClientCAs: pool,
- ClientAuth: tls.ClientAuthType(app.Cfg.Listen.ClientAuth),
- }
- }
- if err := app.Server.ListenAndServeTLS(app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile); err != nil {
- logs.Critical("ListenAndServeTLS: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- }
- }()
-
- }
- if app.Cfg.Listen.EnableHTTP {
- go func() {
- app.Server.Addr = addr
- logs.Info("http server Running on http://%s", app.Server.Addr)
- if app.Cfg.Listen.ListenTCP4 {
- ln, err := net.Listen("tcp4", app.Server.Addr)
- if err != nil {
- logs.Critical("ListenAndServe: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- return
- }
- if err = app.Server.Serve(ln); err != nil {
- logs.Critical("ListenAndServe: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- return
- }
- } else {
- if err := app.Server.ListenAndServe(); err != nil {
- logs.Critical("ListenAndServe: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- }
- }
- }()
- }
- <-endRunning
-}
-
-// Router see HttpServer.Router
-func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *HttpServer {
- return BeeApp.Router(rootpath, c, mappingMethods...)
-}
-
-// Router adds a patterned controller handler to BeeApp.
-// it's an alias method of HttpServer.Router.
-// usage:
-// simple router
-// beego.Router("/admin", &admin.UserController{})
-// beego.Router("/admin/index", &admin.ArticleController{})
-//
-// regex router
-//
-// beego.Router("/api/:id([0-9]+)", &controllers.RController{})
-//
-// custom rules
-// beego.Router("/api/list",&RestController{},"*:ListFood")
-// beego.Router("/api/create",&RestController{},"post:CreateFood")
-// beego.Router("/api/update",&RestController{},"put:UpdateFood")
-// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
-func (app *HttpServer) Router(rootPath string, c ControllerInterface, mappingMethods ...string) *HttpServer {
- app.Handlers.Add(rootPath, c, mappingMethods...)
- return app
-}
-
-// UnregisterFixedRoute see HttpServer.UnregisterFixedRoute
-func UnregisterFixedRoute(fixedRoute string, method string) *HttpServer {
- return BeeApp.UnregisterFixedRoute(fixedRoute, method)
-}
-
-// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
-// in web applications that inherit most routes from a base webapp via the underscore
-// import, and aim to overwrite only certain paths.
-// The method parameter can be empty or "*" for all HTTP methods, or a particular
-// method type (e.g. "GET" or "POST") for selective removal.
-//
-// Usage (replace "GET" with "*" for all methods):
-// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
-// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
-func (app *HttpServer) UnregisterFixedRoute(fixedRoute string, method string) *HttpServer {
- subPaths := splitPath(fixedRoute)
- if method == "" || method == "*" {
- for m := range HTTPMETHOD {
- if _, ok := app.Handlers.routers[m]; !ok {
- continue
- }
- if app.Handlers.routers[m].prefix == strings.Trim(fixedRoute, "/ ") {
- findAndRemoveSingleTree(app.Handlers.routers[m])
- continue
- }
- findAndRemoveTree(subPaths, app.Handlers.routers[m], m)
- }
- return app
- }
- // Single HTTP method
- um := strings.ToUpper(method)
- if _, ok := app.Handlers.routers[um]; ok {
- if app.Handlers.routers[um].prefix == strings.Trim(fixedRoute, "/ ") {
- findAndRemoveSingleTree(app.Handlers.routers[um])
- return app
- }
- findAndRemoveTree(subPaths, app.Handlers.routers[um], um)
- }
- return app
-}
-
-func findAndRemoveTree(paths []string, entryPointTree *Tree, method string) {
- for i := range entryPointTree.fixrouters {
- if entryPointTree.fixrouters[i].prefix == paths[0] {
- if len(paths) == 1 {
- if len(entryPointTree.fixrouters[i].fixrouters) > 0 {
- // If the route had children subtrees, remove just the functional leaf,
- // to allow children to function as before
- if len(entryPointTree.fixrouters[i].leaves) > 0 {
- entryPointTree.fixrouters[i].leaves[0] = nil
- entryPointTree.fixrouters[i].leaves = entryPointTree.fixrouters[i].leaves[1:]
- }
- } else {
- // Remove the *Tree from the fixrouters slice
- entryPointTree.fixrouters[i] = nil
-
- if i == len(entryPointTree.fixrouters)-1 {
- entryPointTree.fixrouters = entryPointTree.fixrouters[:i]
- } else {
- entryPointTree.fixrouters = append(entryPointTree.fixrouters[:i], entryPointTree.fixrouters[i+1:len(entryPointTree.fixrouters)]...)
- }
- }
- return
- }
- findAndRemoveTree(paths[1:], entryPointTree.fixrouters[i], method)
- }
- }
-}
-
-func findAndRemoveSingleTree(entryPointTree *Tree) {
- if entryPointTree == nil {
- return
- }
- if len(entryPointTree.fixrouters) > 0 {
- // If the route had children subtrees, remove just the functional leaf,
- // to allow children to function as before
- if len(entryPointTree.leaves) > 0 {
- entryPointTree.leaves[0] = nil
- entryPointTree.leaves = entryPointTree.leaves[1:]
- }
- }
-}
-
-// Include see HttpServer.Include
-func Include(cList ...ControllerInterface) *HttpServer {
- return BeeApp.Include(cList...)
-}
-
-// Include will generate router file in the router/xxx.go from the controller's comments
-// usage:
-// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
-// type BankAccount struct{
-// beego.Controller
-// }
-//
-// register the function
-// func (b *BankAccount)Mapping(){
-// b.Mapping("ShowAccount" , b.ShowAccount)
-// b.Mapping("ModifyAccount", b.ModifyAccount)
-// }
-//
-// //@router /account/:id [get]
-// func (b *BankAccount) ShowAccount(){
-// //logic
-// }
-//
-//
-// //@router /account/:id [post]
-// func (b *BankAccount) ModifyAccount(){
-// //logic
-// }
-//
-// the comments @router url methodlist
-// url support all the function Router's pattern
-// methodlist [get post head put delete options *]
-func (app *HttpServer) Include(cList ...ControllerInterface) *HttpServer {
- app.Handlers.Include(cList...)
- return app
-}
-
-// RESTRouter see HttpServer.RESTRouter
-func RESTRouter(rootpath string, c ControllerInterface) *HttpServer {
- return BeeApp.RESTRouter(rootpath, c)
-}
-
-// RESTRouter adds a restful controller handler to BeeApp.
-// its' controller implements beego.ControllerInterface and
-// defines a param "pattern/:objectId" to visit each resource.
-func (app *HttpServer) RESTRouter(rootpath string, c ControllerInterface) *HttpServer {
- app.Router(rootpath, c)
- app.Router(path.Join(rootpath, ":objectId"), c)
- return app
-}
-
-// AutoRouter see HttpServer.AutoRouter
-func AutoRouter(c ControllerInterface) *HttpServer {
- return BeeApp.AutoRouter(c)
-}
-
-// AutoRouter adds defined controller handler to BeeApp.
-// it's same to HttpServer.AutoRouter.
-// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
-// visit the url /main/list to exec List function or /main/page to exec Page function.
-func (app *HttpServer) AutoRouter(c ControllerInterface) *HttpServer {
- app.Handlers.AddAuto(c)
- return app
-}
-
-// AutoPrefix see HttpServer.AutoPrefix
-func AutoPrefix(prefix string, c ControllerInterface) *HttpServer {
- return BeeApp.AutoPrefix(prefix, c)
-}
-
-// AutoPrefix adds controller handler to BeeApp with prefix.
-// it's same to HttpServer.AutoRouterWithPrefix.
-// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page,
-// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
-func (app *HttpServer) AutoPrefix(prefix string, c ControllerInterface) *HttpServer {
- app.Handlers.AddAutoPrefix(prefix, c)
- return app
-}
-
-// Get see HttpServer.Get
-func Get(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Get(rootpath, f)
-}
-
-// Get used to register router for Get method
-// usage:
-// beego.Get("/", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Get(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Get(rootpath, f)
- return app
-}
-
-// Post see HttpServer.Post
-func Post(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Post(rootpath, f)
-}
-
-// Post used to register router for Post method
-// usage:
-// beego.Post("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Post(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Post(rootpath, f)
- return app
-}
-
-// Delete see HttpServer.Delete
-func Delete(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Delete(rootpath, f)
-}
-
-// Delete used to register router for Delete method
-// usage:
-// beego.Delete("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Delete(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Delete(rootpath, f)
- return app
-}
-
-// Put see HttpServer.Put
-func Put(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Put(rootpath, f)
-}
-
-// Put used to register router for Put method
-// usage:
-// beego.Put("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Put(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Put(rootpath, f)
- return app
-}
-
-// Head see HttpServer.Head
-func Head(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Head(rootpath, f)
-}
-
-// Head used to register router for Head method
-// usage:
-// beego.Head("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Head(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Head(rootpath, f)
- return app
-}
-
-// Options see HttpServer.Options
-func Options(rootpath string, f FilterFunc) *HttpServer {
- BeeApp.Handlers.Options(rootpath, f)
- return BeeApp
-}
-
-// Options used to register router for Options method
-// usage:
-// beego.Options("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Options(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Options(rootpath, f)
- return app
-}
-
-// Patch see HttpServer.Patch
-func Patch(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Patch(rootpath, f)
-}
-
-// Patch used to register router for Patch method
-// usage:
-// beego.Patch("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Patch(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Patch(rootpath, f)
- return app
-}
-
-// Any see HttpServer.Any
-func Any(rootpath string, f FilterFunc) *HttpServer {
- return BeeApp.Any(rootpath, f)
-}
-
-// Any used to register router for all methods
-// usage:
-// beego.Any("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (app *HttpServer) Any(rootpath string, f FilterFunc) *HttpServer {
- app.Handlers.Any(rootpath, f)
- return app
-}
-
-// Handler see HttpServer.Handler
-func Handler(rootpath string, h http.Handler, options ...interface{}) *HttpServer {
- return BeeApp.Handler(rootpath, h, options...)
-}
-
-// Handler used to register a Handler router
-// usage:
-// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
-// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
-// }))
-func (app *HttpServer) Handler(rootpath string, h http.Handler, options ...interface{}) *HttpServer {
- app.Handlers.Handler(rootpath, h, options...)
- return app
-}
-
-// InserFilter see HttpServer.InsertFilter
-func InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) *HttpServer {
- return BeeApp.InsertFilter(pattern, pos, filter, opts...)
-}
-
-// InsertFilter adds a FilterFunc with pattern condition and action constant.
-// The pos means action constant including
-// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
-// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
-func (app *HttpServer) InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) *HttpServer {
- app.Handlers.InsertFilter(pattern, pos, filter, opts...)
- return app
-}
-
-// InsertFilterChain see HttpServer.InsertFilterChain
-func InsertFilterChain(pattern string, filterChain FilterChain, opts ...FilterOpt) *HttpServer {
- return BeeApp.InsertFilterChain(pattern, filterChain, opts...)
-}
-
-// InsertFilterChain adds a FilterFunc built by filterChain.
-// This filter will be executed before all filters.
-// the filter's behavior like stack's behavior
-// and the last filter is serving the http request
-func (app *HttpServer) InsertFilterChain(pattern string, filterChain FilterChain, opts ...FilterOpt) *HttpServer {
- app.Handlers.InsertFilterChain(pattern, filterChain, opts...)
- return app
-}
-
-func (app *HttpServer) initAddr(addr string) {
- strs := strings.Split(addr, ":")
- if len(strs) > 0 && strs[0] != "" {
- app.Cfg.Listen.HTTPAddr = strs[0]
- app.Cfg.Listen.Domains = []string{strs[0]}
- }
- if len(strs) > 1 && strs[1] != "" {
- app.Cfg.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
- }
-}
-
-func (app *HttpServer) LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
- // Skip logging if AccessLogs config is false
- if !app.Cfg.Log.AccessLogs {
- return
- }
- // Skip logging static requests unless EnableStaticLogs config is true
- if !app.Cfg.Log.EnableStaticLogs && DefaultAccessLogFilter.Filter(ctx) {
- return
- }
- var (
- requestTime time.Time
- elapsedTime time.Duration
- r = ctx.Request
- )
- if startTime != nil {
- requestTime = *startTime
- elapsedTime = time.Since(*startTime)
- }
- record := &logs.AccessLogRecord{
- RemoteAddr: ctx.Input.IP(),
- RequestTime: requestTime,
- RequestMethod: r.Method,
- Request: fmt.Sprintf("%s %s %s", r.Method, r.RequestURI, r.Proto),
- ServerProtocol: r.Proto,
- Host: r.Host,
- Status: statusCode,
- ElapsedTime: elapsedTime,
- HTTPReferrer: r.Header.Get("Referer"),
- HTTPUserAgent: r.Header.Get("User-Agent"),
- RemoteUser: r.Header.Get("Remote-User"),
- BodyBytesSent: r.ContentLength,
- }
- logs.AccessLog(record, app.Cfg.Log.AccessLogsFormat)
-}
-
-// PrintTree prints all registered routers.
-func (app *HttpServer) PrintTree() M {
- var (
- content = M{}
- methods = []string{}
- methodsData = make(M)
- )
- for method, t := range app.Handlers.routers {
-
- resultList := new([][]string)
-
- printTree(resultList, t)
-
- methods = append(methods, template.HTMLEscapeString(method))
- methodsData[template.HTMLEscapeString(method)] = resultList
- }
-
- content["Data"] = methodsData
- content["Methods"] = methods
- return content
-}
-
-func printTree(resultList *[][]string, t *Tree) {
- for _, tr := range t.fixrouters {
- printTree(resultList, tr)
- }
- if t.wildcard != nil {
- printTree(resultList, t.wildcard)
- }
- for _, l := range t.leaves {
- if v, ok := l.runObject.(*ControllerInfo); ok {
- if v.routerType == routerTypeBeego {
- var result = []string{
- template.HTMLEscapeString(v.pattern),
- template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
- template.HTMLEscapeString(v.controllerType.String()),
- }
- *resultList = append(*resultList, result)
- } else if v.routerType == routerTypeRESTFul {
- var result = []string{
- template.HTMLEscapeString(v.pattern),
- template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
- "",
- }
- *resultList = append(*resultList, result)
- } else if v.routerType == routerTypeHandler {
- var result = []string{
- template.HTMLEscapeString(v.pattern),
- "",
- "",
- }
- *resultList = append(*resultList, result)
- }
- }
- }
-}
-
-func (app *HttpServer) reportFilter() M {
- filterTypeData := make(M)
- // filterTypes := []string{}
- if app.Handlers.enableFilter {
- // var filterType string
- for k, fr := range map[int]string{
- BeforeStatic: "Before Static",
- BeforeRouter: "Before Router",
- BeforeExec: "Before Exec",
- AfterExec: "After Exec",
- FinishRouter: "Finish Router",
- } {
- if bf := app.Handlers.filters[k]; len(bf) > 0 {
- resultList := new([][]string)
- for _, f := range bf {
- var result = []string{
- // void xss
- template.HTMLEscapeString(f.pattern),
- template.HTMLEscapeString(utils.GetFuncName(f.filterFunc)),
- }
- *resultList = append(*resultList, result)
- }
- filterTypeData[fr] = resultList
- }
- }
- }
-
- return filterTypeData
-}
diff --git a/server/web/server_test.go b/server/web/server_test.go
deleted file mode 100644
index 0b0c601c..00000000
--- a/server/web/server_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestNewHttpServerWithCfg(t *testing.T) {
-
- BConfig.AppName = "Before"
- svr := NewHttpServerWithCfg(BConfig)
- svr.Cfg.AppName = "hello"
- assert.Equal(t, "hello", BConfig.AppName)
-
-}
diff --git a/server/web/session/couchbase/sess_couchbase_test.go b/server/web/session/couchbase/sess_couchbase_test.go
deleted file mode 100644
index 5959f9c3..00000000
--- a/server/web/session/couchbase/sess_couchbase_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package couchbase
-
-import (
- "context"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestProvider_SessionInit(t *testing.T) {
- // using old style
- savePath := `http://host:port/,Pool,Bucket`
- cp := &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "http://host:port/", cp.SavePath)
- assert.Equal(t, "Pool", cp.Pool)
- assert.Equal(t, "Bucket", cp.Bucket)
- assert.Equal(t, int64(12), cp.maxlifetime)
-
- savePath = `
-{ "save_path": "my save path", "pool": "mypool", "bucket": "mybucket"}
-`
- cp = &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "my save path", cp.SavePath)
- assert.Equal(t, "mypool", cp.Pool)
- assert.Equal(t, "mybucket", cp.Bucket)
- assert.Equal(t, int64(12), cp.maxlifetime)
-}
diff --git a/server/web/session/ledis/ledis_session_test.go b/server/web/session/ledis/ledis_session_test.go
deleted file mode 100644
index 1cfb3ed1..00000000
--- a/server/web/session/ledis/ledis_session_test.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ledis
-
-import (
- "context"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestProvider_SessionInit(t *testing.T) {
- // using old style
- savePath := `http://host:port/,100`
- cp := &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "http://host:port/", cp.SavePath)
- assert.Equal(t, 100, cp.Db)
- assert.Equal(t, int64(12), cp.maxlifetime)
-
- savePath = `
-{ "save_path": "my save path", "db": 100}
-`
- cp = &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "my save path", cp.SavePath)
- assert.Equal(t, 100, cp.Db)
- assert.Equal(t, int64(12), cp.maxlifetime)
-}
diff --git a/server/web/session/redis/sess_redis_test.go b/server/web/session/redis/sess_redis_test.go
deleted file mode 100644
index 64dbc9f9..00000000
--- a/server/web/session/redis/sess_redis_test.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package redis
-
-import (
- "context"
- "fmt"
- "net/http"
- "net/http/httptest"
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/server/web/session"
-)
-
-func TestRedis(t *testing.T) {
- sessionConfig := &session.ManagerConfig{
- CookieName: "gosessionid",
- EnableSetCookie: true,
- Gclifetime: 3600,
- Maxlifetime: 3600,
- Secure: false,
- CookieLifeTime: 3600,
- }
-
- redisAddr := os.Getenv("REDIS_ADDR")
- if redisAddr == "" {
- redisAddr = "127.0.0.1:6379"
- }
-
- sessionConfig.ProviderConfig = fmt.Sprintf("%s,100,,0,30", redisAddr)
- globalSession, err := session.NewManager("redis", sessionConfig)
- if err != nil {
- t.Fatal("could not create manager:", err)
- }
-
- go globalSession.GC()
-
- r, _ := http.NewRequest("GET", "/", nil)
- w := httptest.NewRecorder()
-
- sess, err := globalSession.SessionStart(w, r)
- if err != nil {
- t.Fatal("session start failed:", err)
- }
- defer sess.SessionRelease(nil, w)
-
- // SET AND GET
- err = sess.Set(nil, "username", "astaxie")
- if err != nil {
- t.Fatal("set username failed:", err)
- }
- username := sess.Get(nil, "username")
- if username != "astaxie" {
- t.Fatal("get username failed")
- }
-
- // DELETE
- err = sess.Delete(nil, "username")
- if err != nil {
- t.Fatal("delete username failed:", err)
- }
- username = sess.Get(nil, "username")
- if username != nil {
- t.Fatal("delete username failed")
- }
-
- // FLUSH
- err = sess.Set(nil, "username", "astaxie")
- if err != nil {
- t.Fatal("set failed:", err)
- }
- err = sess.Set(nil, "password", "1qaz2wsx")
- if err != nil {
- t.Fatal("set failed:", err)
- }
- username = sess.Get(nil, "username")
- if username != "astaxie" {
- t.Fatal("get username failed")
- }
- password := sess.Get(nil, "password")
- if password != "1qaz2wsx" {
- t.Fatal("get password failed")
- }
- err = sess.Flush(nil)
- if err != nil {
- t.Fatal("flush failed:", err)
- }
- username = sess.Get(nil, "username")
- if username != nil {
- t.Fatal("flush failed")
- }
- password = sess.Get(nil, "password")
- if password != nil {
- t.Fatal("flush failed")
- }
-
- sess.SessionRelease(nil, w)
-}
-
-func TestProvider_SessionInit(t *testing.T) {
-
- savePath := `
-{ "save_path": "my save path", "idle_timeout": "3s"}
-`
- cp := &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "my save path", cp.SavePath)
- assert.Equal(t, 3*time.Second, cp.idleTimeout)
- assert.Equal(t, int64(12), cp.maxlifetime)
-}
diff --git a/server/web/session/redis_cluster/redis_cluster_test.go b/server/web/session/redis_cluster/redis_cluster_test.go
deleted file mode 100644
index 0192cd87..00000000
--- a/server/web/session/redis_cluster/redis_cluster_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package redis_cluster
-
-import (
- "context"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestProvider_SessionInit(t *testing.T) {
-
- savePath := `
-{ "save_path": "my save path", "idle_timeout": "3s"}
-`
- cp := &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "my save path", cp.SavePath)
- assert.Equal(t, 3*time.Second, cp.idleTimeout)
- assert.Equal(t, int64(12), cp.maxlifetime)
-}
diff --git a/server/web/session/redis_sentinel/sess_redis_sentinel_test.go b/server/web/session/redis_sentinel/sess_redis_sentinel_test.go
deleted file mode 100644
index f052a14a..00000000
--- a/server/web/session/redis_sentinel/sess_redis_sentinel_test.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package redis_sentinel
-
-import (
- "context"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/server/web/session"
-)
-
-func TestRedisSentinel(t *testing.T) {
- sessionConfig := &session.ManagerConfig{
- CookieName: "gosessionid",
- EnableSetCookie: true,
- Gclifetime: 3600,
- Maxlifetime: 3600,
- Secure: false,
- CookieLifeTime: 3600,
- ProviderConfig: "127.0.0.1:6379,100,,0,master",
- }
- globalSessions, e := session.NewManager("redis_sentinel", sessionConfig)
- if e != nil {
- t.Log(e)
- return
- }
- // todo test if e==nil
- go globalSessions.GC()
-
- r, _ := http.NewRequest("GET", "/", nil)
- w := httptest.NewRecorder()
-
- sess, err := globalSessions.SessionStart(w, r)
- if err != nil {
- t.Fatal("session start failed:", err)
- }
- defer sess.SessionRelease(nil, w)
-
- // SET AND GET
- err = sess.Set(nil, "username", "astaxie")
- if err != nil {
- t.Fatal("set username failed:", err)
- }
- username := sess.Get(nil, "username")
- if username != "astaxie" {
- t.Fatal("get username failed")
- }
-
- // DELETE
- err = sess.Delete(nil, "username")
- if err != nil {
- t.Fatal("delete username failed:", err)
- }
- username = sess.Get(nil, "username")
- if username != nil {
- t.Fatal("delete username failed")
- }
-
- // FLUSH
- err = sess.Set(nil, "username", "astaxie")
- if err != nil {
- t.Fatal("set failed:", err)
- }
- err = sess.Set(nil, "password", "1qaz2wsx")
- if err != nil {
- t.Fatal("set failed:", err)
- }
- username = sess.Get(nil, "username")
- if username != "astaxie" {
- t.Fatal("get username failed")
- }
- password := sess.Get(nil, "password")
- if password != "1qaz2wsx" {
- t.Fatal("get password failed")
- }
- err = sess.Flush(nil)
- if err != nil {
- t.Fatal("flush failed:", err)
- }
- username = sess.Get(nil, "username")
- if username != nil {
- t.Fatal("flush failed")
- }
- password = sess.Get(nil, "password")
- if password != nil {
- t.Fatal("flush failed")
- }
-
- sess.SessionRelease(nil, w)
-
-}
-
-func TestProvider_SessionInit(t *testing.T) {
-
- savePath := `
-{ "save_path": "my save path", "idle_timeout": "3s"}
-`
- cp := &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "my save path", cp.SavePath)
- assert.Equal(t, 3*time.Second, cp.idleTimeout)
- assert.Equal(t, int64(12), cp.maxlifetime)
-}
diff --git a/server/web/session/sess_cookie_test.go b/server/web/session/sess_cookie_test.go
deleted file mode 100644
index a9fc876d..00000000
--- a/server/web/session/sess_cookie_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package session
-
-import (
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
-)
-
-func TestCookie(t *testing.T) {
- config := `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}`
- conf := new(ManagerConfig)
- if err := json.Unmarshal([]byte(config), conf); err != nil {
- t.Fatal("json decode error", err)
- }
- globalSessions, err := NewManager("cookie", conf)
- if err != nil {
- t.Fatal("init cookie session err", err)
- }
- r, _ := http.NewRequest("GET", "/", nil)
- w := httptest.NewRecorder()
- sess, err := globalSessions.SessionStart(w, r)
- if err != nil {
- t.Fatal("set error,", err)
- }
- err = sess.Set(nil, "username", "astaxie")
- if err != nil {
- t.Fatal("set error,", err)
- }
- if username := sess.Get(nil, "username"); username != "astaxie" {
- t.Fatal("get username error")
- }
- sess.SessionRelease(nil, w)
- if cookiestr := w.Header().Get("Set-Cookie"); cookiestr == "" {
- t.Fatal("setcookie error")
- } else {
- parts := strings.Split(strings.TrimSpace(cookiestr), ";")
- for k, v := range parts {
- nameval := strings.Split(v, "=")
- if k == 0 && nameval[0] != "gosessionid" {
- t.Fatal("error")
- }
- }
- }
-}
-
-func TestDestorySessionCookie(t *testing.T) {
- config := `{"cookieName":"gosessionid","enableSetCookie":true,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}`
- conf := new(ManagerConfig)
- if err := json.Unmarshal([]byte(config), conf); err != nil {
- t.Fatal("json decode error", err)
- }
- globalSessions, err := NewManager("cookie", conf)
- if err != nil {
- t.Fatal("init cookie session err", err)
- }
-
- r, _ := http.NewRequest("GET", "/", nil)
- w := httptest.NewRecorder()
- session, err := globalSessions.SessionStart(w, r)
- if err != nil {
- t.Fatal("session start err,", err)
- }
-
- // request again ,will get same sesssion id .
- r1, _ := http.NewRequest("GET", "/", nil)
- r1.Header.Set("Cookie", w.Header().Get("Set-Cookie"))
- w = httptest.NewRecorder()
- newSession, err := globalSessions.SessionStart(w, r1)
- if err != nil {
- t.Fatal("session start err,", err)
- }
- if newSession.SessionID(nil) != session.SessionID(nil) {
- t.Fatal("get cookie session id is not the same again.")
- }
-
- // After destroy session , will get a new session id .
- globalSessions.SessionDestroy(w, r1)
- r2, _ := http.NewRequest("GET", "/", nil)
- r2.Header.Set("Cookie", w.Header().Get("Set-Cookie"))
-
- w = httptest.NewRecorder()
- newSession, err = globalSessions.SessionStart(w, r2)
- if err != nil {
- t.Fatal("session start error")
- }
- if newSession.SessionID(nil) == session.SessionID(nil) {
- t.Fatal("after destroy session and reqeust again ,get cookie session id is same.")
- }
-}
diff --git a/server/web/session/sess_file_test.go b/server/web/session/sess_file_test.go
deleted file mode 100644
index f40de69f..00000000
--- a/server/web/session/sess_file_test.go
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package session
-
-import (
- "context"
- "fmt"
- "os"
- "sync"
- "testing"
- "time"
-)
-
-const sid = "Session_id"
-const sidNew = "Session_id_new"
-const sessionPath = "./_session_runtime"
-
-var (
- mutex sync.Mutex
-)
-
-func TestFileProvider_SessionInit(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
- if fp.maxlifetime != 180 {
- t.Error()
- }
-
- if fp.savePath != sessionPath {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionExist(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- exists, err := fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if exists {
- t.Error()
- }
-
- _, err = fp.SessionRead(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
-
- exists, err = fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if !exists {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionExist2(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- exists, err := fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if exists {
- t.Error()
- }
-
- exists, err = fp.SessionExist(context.Background(), "")
- if err == nil {
- t.Error()
- }
- if exists {
- t.Error()
- }
-
- exists, err = fp.SessionExist(context.Background(), "1")
- if err == nil {
- t.Error()
- }
- if exists {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionRead(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- s, err := fp.SessionRead(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
-
- _ = s.Set(nil, "sessionValue", 18975)
- v := s.Get(nil, "sessionValue")
-
- if v.(int) != 18975 {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionRead1(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- _, err := fp.SessionRead(context.Background(), "")
- if err == nil {
- t.Error(err)
- }
-
- _, err = fp.SessionRead(context.Background(), "1")
- if err == nil {
- t.Error(err)
- }
-}
-
-func TestFileProvider_SessionAll(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- sessionCount := 546
-
- for i := 1; i <= sessionCount; i++ {
- _, err := fp.SessionRead(context.Background(), fmt.Sprintf("%s_%d", sid, i))
- if err != nil {
- t.Error(err)
- }
- }
-
- if fp.SessionAll(nil) != sessionCount {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionRegenerate(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- _, err := fp.SessionRead(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
-
- exists, err := fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if !exists {
- t.Error()
- }
-
- _, err = fp.SessionRegenerate(context.Background(), sid, sidNew)
- if err != nil {
- t.Error(err)
- }
-
- exists, err = fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if exists {
- t.Error()
- }
-
- exists, err = fp.SessionExist(context.Background(), sidNew)
- if err != nil {
- t.Error(err)
- }
- if !exists {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionDestroy(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- _, err := fp.SessionRead(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
-
- exists, err := fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if !exists {
- t.Error()
- }
-
- err = fp.SessionDestroy(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
-
- exists, err = fp.SessionExist(context.Background(), sid)
- if err != nil {
- t.Error(err)
- }
- if exists {
- t.Error()
- }
-}
-
-func TestFileProvider_SessionGC(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 1, sessionPath)
-
- sessionCount := 412
-
- for i := 1; i <= sessionCount; i++ {
- _, err := fp.SessionRead(context.Background(), fmt.Sprintf("%s_%d", sid, i))
- if err != nil {
- t.Error(err)
- }
- }
-
- time.Sleep(2 * time.Second)
-
- fp.SessionGC(nil)
- if fp.SessionAll(nil) != 0 {
- t.Error()
- }
-}
-
-func TestFileSessionStore_Set(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- sessionCount := 100
- s, _ := fp.SessionRead(context.Background(), sid)
- for i := 1; i <= sessionCount; i++ {
- err := s.Set(nil, i, i)
- if err != nil {
- t.Error(err)
- }
- }
-}
-
-func TestFileSessionStore_Get(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- sessionCount := 100
- s, _ := fp.SessionRead(context.Background(), sid)
- for i := 1; i <= sessionCount; i++ {
- _ = s.Set(nil, i, i)
-
- v := s.Get(nil, i)
- if v.(int) != i {
- t.Error()
- }
- }
-}
-
-func TestFileSessionStore_Delete(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- s, _ := fp.SessionRead(context.Background(), sid)
- s.Set(nil, "1", 1)
-
- if s.Get(nil, "1") == nil {
- t.Error()
- }
-
- s.Delete(nil, "1")
-
- if s.Get(nil, "1") != nil {
- t.Error()
- }
-}
-
-func TestFileSessionStore_Flush(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- sessionCount := 100
- s, _ := fp.SessionRead(context.Background(), sid)
- for i := 1; i <= sessionCount; i++ {
- _ = s.Set(nil, i, i)
- }
-
- _ = s.Flush(nil)
-
- for i := 1; i <= sessionCount; i++ {
- if s.Get(nil, i) != nil {
- t.Error()
- }
- }
-}
-
-func TestFileSessionStore_SessionID(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
-
- sessionCount := 85
-
- for i := 1; i <= sessionCount; i++ {
- s, err := fp.SessionRead(context.Background(), fmt.Sprintf("%s_%d", sid, i))
- if err != nil {
- t.Error(err)
- }
- if s.SessionID(nil) != fmt.Sprintf("%s_%d", sid, i) {
- t.Error(err)
- }
- }
-}
-
-func TestFileSessionStore_SessionRelease(t *testing.T) {
- mutex.Lock()
- defer mutex.Unlock()
- os.RemoveAll(sessionPath)
- defer os.RemoveAll(sessionPath)
- fp := &FileProvider{}
-
- _ = fp.SessionInit(context.Background(), 180, sessionPath)
- filepder.savePath = sessionPath
- sessionCount := 85
-
- for i := 1; i <= sessionCount; i++ {
- s, err := fp.SessionRead(context.Background(), fmt.Sprintf("%s_%d", sid, i))
- if err != nil {
- t.Error(err)
- }
-
- s.Set(nil, i, i)
- s.SessionRelease(nil, nil)
- }
-
- for i := 1; i <= sessionCount; i++ {
- s, err := fp.SessionRead(context.Background(), fmt.Sprintf("%s_%d", sid, i))
- if err != nil {
- t.Error(err)
- }
-
- if s.Get(nil, i).(int) != i {
- t.Error()
- }
- }
-}
diff --git a/server/web/session/sess_mem_test.go b/server/web/session/sess_mem_test.go
deleted file mode 100644
index e6d35476..00000000
--- a/server/web/session/sess_mem_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package session
-
-import (
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
-)
-
-func TestMem(t *testing.T) {
- config := `{"cookieName":"gosessionid","gclifetime":10, "enableSetCookie":true}`
- conf := new(ManagerConfig)
- if err := json.Unmarshal([]byte(config), conf); err != nil {
- t.Fatal("json decode error", err)
- }
- globalSessions, _ := NewManager("memory", conf)
- go globalSessions.GC()
- r, _ := http.NewRequest("GET", "/", nil)
- w := httptest.NewRecorder()
- sess, err := globalSessions.SessionStart(w, r)
- if err != nil {
- t.Fatal("set error,", err)
- }
- defer sess.SessionRelease(nil, w)
- err = sess.Set(nil, "username", "astaxie")
- if err != nil {
- t.Fatal("set error,", err)
- }
- if username := sess.Get(nil, "username"); username != "astaxie" {
- t.Fatal("get username error")
- }
- if cookiestr := w.Header().Get("Set-Cookie"); cookiestr == "" {
- t.Fatal("setcookie error")
- } else {
- parts := strings.Split(strings.TrimSpace(cookiestr), ";")
- for k, v := range parts {
- nameval := strings.Split(v, "=")
- if k == 0 && nameval[0] != "gosessionid" {
- t.Fatal("error")
- }
- }
- }
-}
diff --git a/server/web/session/ssdb/sess_ssdb_test.go b/server/web/session/ssdb/sess_ssdb_test.go
deleted file mode 100644
index 3de5da0a..00000000
--- a/server/web/session/ssdb/sess_ssdb_test.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ssdb
-
-import (
- "context"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestProvider_SessionInit(t *testing.T) {
- // using old style
- savePath := `localhost:8080`
- cp := &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "localhost", cp.Host)
- assert.Equal(t, 8080, cp.Port)
- assert.Equal(t, int64(12), cp.maxLifetime)
-
- savePath = `
-{ "host": "localhost", "port": 8080}
-`
- cp = &Provider{}
- cp.SessionInit(context.Background(), 12, savePath)
- assert.Equal(t, "localhost", cp.Host)
- assert.Equal(t, 8080, cp.Port)
- assert.Equal(t, int64(12), cp.maxLifetime)
-}
diff --git a/server/web/statistics_test.go b/server/web/statistics_test.go
deleted file mode 100644
index 7c83e15a..00000000
--- a/server/web/statistics_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package web
-
-import (
- "encoding/json"
- "testing"
- "time"
-)
-
-func TestStatics(t *testing.T) {
- StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000))
- StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000))
- StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000))
- StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000))
- StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000))
- StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000))
- StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400))
- t.Log(StatisticsMap.GetMap())
-
- data := StatisticsMap.GetMapData()
- b, err := json.Marshal(data)
- if err != nil {
- t.Errorf(err.Error())
- }
-
- t.Log(string(b))
-}
diff --git a/server/web/session/README.md b/session/README.md
similarity index 98%
rename from server/web/session/README.md
rename to session/README.md
index a5c3bd6d..6d0a297e 100644
--- a/server/web/session/README.md
+++ b/session/README.md
@@ -101,7 +101,7 @@ Maybe you will find the **memory** provider is a good example.
type Provider interface {
SessionInit(gclifetime int64, config string) error
SessionRead(sid string) (SessionStore, error)
- SessionExist(sid string) (bool, error)
+ SessionExist(sid string) bool
SessionRegenerate(oldsid, sid string) (SessionStore, error)
SessionDestroy(sid string) error
SessionAll() int //get all active session
diff --git a/server/web/session/couchbase/sess_couchbase.go b/session/couchbase/sess_couchbase.go
similarity index 69%
rename from server/web/session/couchbase/sess_couchbase.go
rename to session/couchbase/sess_couchbase.go
index 7f15956a..707d042c 100644
--- a/server/web/session/couchbase/sess_couchbase.go
+++ b/session/couchbase/sess_couchbase.go
@@ -33,15 +33,13 @@
package couchbase
import (
- "context"
- "encoding/json"
"net/http"
"strings"
"sync"
couchbase "github.com/couchbase/go-couchbase"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/astaxie/beego/session"
)
var couchbpder = &Provider{}
@@ -58,14 +56,14 @@ type SessionStore struct {
// Provider couchabse provided
type Provider struct {
maxlifetime int64
- SavePath string `json:"save_path"`
- Pool string `json:"pool"`
- Bucket string `json:"bucket"`
+ savePath string
+ pool string
+ bucket string
b *couchbase.Bucket
}
// Set value to couchabse session
-func (cs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (cs *SessionStore) Set(key, value interface{}) error {
cs.lock.Lock()
defer cs.lock.Unlock()
cs.values[key] = value
@@ -73,7 +71,7 @@ func (cs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value from couchabse session
-func (cs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (cs *SessionStore) Get(key interface{}) interface{} {
cs.lock.RLock()
defer cs.lock.RUnlock()
if v, ok := cs.values[key]; ok {
@@ -83,7 +81,7 @@ func (cs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in couchbase session by given key
-func (cs *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (cs *SessionStore) Delete(key interface{}) error {
cs.lock.Lock()
defer cs.lock.Unlock()
delete(cs.values, key)
@@ -91,7 +89,7 @@ func (cs *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush Clean all values in couchbase session
-func (cs *SessionStore) Flush(context.Context) error {
+func (cs *SessionStore) Flush() error {
cs.lock.Lock()
defer cs.lock.Unlock()
cs.values = make(map[interface{}]interface{})
@@ -99,12 +97,12 @@ func (cs *SessionStore) Flush(context.Context) error {
}
// SessionID Get couchbase session store id
-func (cs *SessionStore) SessionID(context.Context) string {
+func (cs *SessionStore) SessionID() string {
return cs.sid
}
// SessionRelease Write couchbase session with Gob string
-func (cs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (cs *SessionStore) SessionRelease(w http.ResponseWriter) {
defer cs.b.Close()
bo, err := session.EncodeGob(cs.values)
@@ -116,17 +114,17 @@ func (cs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWrite
}
func (cp *Provider) getBucket() *couchbase.Bucket {
- c, err := couchbase.Connect(cp.SavePath)
+ c, err := couchbase.Connect(cp.savePath)
if err != nil {
return nil
}
- pool, err := c.GetPool(cp.Pool)
+ pool, err := c.GetPool(cp.pool)
if err != nil {
return nil
}
- bucket, err := pool.GetBucket(cp.Bucket)
+ bucket, err := pool.GetBucket(cp.bucket)
if err != nil {
return nil
}
@@ -136,38 +134,25 @@ func (cp *Provider) getBucket() *couchbase.Bucket {
// SessionInit init couchbase session
// savepath like couchbase server REST/JSON URL
-// For v1.x e.g. http://host:port/, Pool, Bucket
-// For v2.x, you should pass json string.
-// e.g. { "save_path": "http://host:port/", "pool": "mypool", "bucket": "mybucket"}
-func (cp *Provider) SessionInit(ctx context.Context, maxlifetime int64, cfg string) error {
+// e.g. http://host:port/, Pool, Bucket
+func (cp *Provider) SessionInit(maxlifetime int64, savePath string) error {
cp.maxlifetime = maxlifetime
- cfg = strings.TrimSpace(cfg)
- // we think this is v2.0, using json to init the session
- if strings.HasPrefix(cfg, "{") {
- return json.Unmarshal([]byte(cfg), cp)
- } else {
- return cp.initOldStyle(cfg)
- }
-}
-
-// initOldStyle keep compatible with v1.x
-func (cp *Provider) initOldStyle(savePath string) error {
configs := strings.Split(savePath, ",")
if len(configs) > 0 {
- cp.SavePath = configs[0]
+ cp.savePath = configs[0]
}
if len(configs) > 1 {
- cp.Pool = configs[1]
+ cp.pool = configs[1]
}
if len(configs) > 2 {
- cp.Bucket = configs[2]
+ cp.bucket = configs[2]
}
return nil
}
// SessionRead read couchbase session by sid
-func (cp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (cp *Provider) SessionRead(sid string) (session.Store, error) {
cp.b = cp.getBucket()
var (
@@ -194,20 +179,20 @@ func (cp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
// SessionExist Check couchbase session exist.
// it checkes sid exist or not.
-func (cp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (cp *Provider) SessionExist(sid string) bool {
cp.b = cp.getBucket()
defer cp.b.Close()
var doc []byte
if err := cp.b.Get(sid, &doc); err != nil || doc == nil {
- return false, err
+ return false
}
- return true, nil
+ return true
}
// SessionRegenerate remove oldsid and use sid to generate new session
-func (cp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (cp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
cp.b = cp.getBucket()
var doc []byte
@@ -239,8 +224,8 @@ func (cp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (
return cs, nil
}
-// SessionDestroy Remove Bucket in this couchbase
-func (cp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+// SessionDestroy Remove bucket in this couchbase
+func (cp *Provider) SessionDestroy(sid string) error {
cp.b = cp.getBucket()
defer cp.b.Close()
@@ -249,11 +234,11 @@ func (cp *Provider) SessionDestroy(ctx context.Context, sid string) error {
}
// SessionGC Recycle
-func (cp *Provider) SessionGC(context.Context) {
+func (cp *Provider) SessionGC() {
}
// SessionAll return all active session
-func (cp *Provider) SessionAll(context.Context) int {
+func (cp *Provider) SessionAll() int {
return 0
}
diff --git a/server/web/session/ledis/ledis_session.go b/session/ledis/ledis_session.go
similarity index 59%
rename from server/web/session/ledis/ledis_session.go
rename to session/ledis/ledis_session.go
index 5b930fcd..ee81df67 100644
--- a/server/web/session/ledis/ledis_session.go
+++ b/session/ledis/ledis_session.go
@@ -2,8 +2,6 @@
package ledis
import (
- "context"
- "encoding/json"
"net/http"
"strconv"
"strings"
@@ -12,7 +10,7 @@ import (
"github.com/ledisdb/ledisdb/config"
"github.com/ledisdb/ledisdb/ledis"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/astaxie/beego/session"
)
var (
@@ -29,7 +27,7 @@ type SessionStore struct {
}
// Set value in ledis session
-func (ls *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (ls *SessionStore) Set(key, value interface{}) error {
ls.lock.Lock()
defer ls.lock.Unlock()
ls.values[key] = value
@@ -37,7 +35,7 @@ func (ls *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value in ledis session
-func (ls *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (ls *SessionStore) Get(key interface{}) interface{} {
ls.lock.RLock()
defer ls.lock.RUnlock()
if v, ok := ls.values[key]; ok {
@@ -47,7 +45,7 @@ func (ls *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in ledis session
-func (ls *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (ls *SessionStore) Delete(key interface{}) error {
ls.lock.Lock()
defer ls.lock.Unlock()
delete(ls.values, key)
@@ -55,7 +53,7 @@ func (ls *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in ledis session
-func (ls *SessionStore) Flush(context.Context) error {
+func (ls *SessionStore) Flush() error {
ls.lock.Lock()
defer ls.lock.Unlock()
ls.values = make(map[interface{}]interface{})
@@ -63,12 +61,12 @@ func (ls *SessionStore) Flush(context.Context) error {
}
// SessionID get ledis session id
-func (ls *SessionStore) SessionID(context.Context) string {
+func (ls *SessionStore) SessionID() string {
return ls.sid
}
// SessionRelease save session values to ledis
-func (ls *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (ls *SessionStore) SessionRelease(w http.ResponseWriter) {
b, err := session.EncodeGob(ls.values)
if err != nil {
return
@@ -80,56 +78,40 @@ func (ls *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWrite
// Provider ledis session provider
type Provider struct {
maxlifetime int64
- SavePath string `json:"save_path"`
- Db int `json:"db"`
+ savePath string
+ db int
}
// SessionInit init ledis session
// savepath like ledis server saveDataPath,pool size
-// v1.x e.g. 127.0.0.1:6379,100
-// v2.x you should pass a json string
-// e.g. { "save_path": "my save path", "db": 100}
-func (lp *Provider) SessionInit(ctx context.Context, maxlifetime int64, cfgStr string) error {
+// e.g. 127.0.0.1:6379,100,astaxie
+func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error {
var err error
lp.maxlifetime = maxlifetime
- cfgStr = strings.TrimSpace(cfgStr)
- // we think cfgStr is v2.0, using json to init the session
- if strings.HasPrefix(cfgStr, "{") {
- err = json.Unmarshal([]byte(cfgStr), lp)
- } else {
- err = lp.initOldStyle(cfgStr)
+ configs := strings.Split(savePath, ",")
+ if len(configs) == 1 {
+ lp.savePath = configs[0]
+ } else if len(configs) == 2 {
+ lp.savePath = configs[0]
+ lp.db, err = strconv.Atoi(configs[1])
+ if err != nil {
+ return err
+ }
}
-
- if err != nil {
- return err
- }
-
cfg := new(config.Config)
- cfg.DataDir = lp.SavePath
+ cfg.DataDir = lp.savePath
var ledisInstance *ledis.Ledis
ledisInstance, err = ledis.Open(cfg)
if err != nil {
return err
}
- c, err = ledisInstance.Select(lp.Db)
- return err
-}
-
-func (lp *Provider) initOldStyle(cfgStr string) error {
- var err error
- configs := strings.Split(cfgStr, ",")
- if len(configs) == 1 {
- lp.SavePath = configs[0]
- } else if len(configs) == 2 {
- lp.SavePath = configs[0]
- lp.Db, err = strconv.Atoi(configs[1])
- }
+ c, err = ledisInstance.Select(lp.db)
return err
}
// SessionRead read ledis session by sid
-func (lp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (lp *Provider) SessionRead(sid string) (session.Store, error) {
var (
kv map[interface{}]interface{}
err error
@@ -150,13 +132,13 @@ func (lp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist check ledis session exist by sid
-func (lp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (lp *Provider) SessionExist(sid string) bool {
count, _ := c.Exists([]byte(sid))
- return count != 0, nil
+ return count != 0
}
// SessionRegenerate generate new sid for ledis session
-func (lp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (lp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
count, _ := c.Exists([]byte(sid))
if count == 0 {
// oldsid doesn't exists, set the new sid directly
@@ -169,21 +151,21 @@ func (lp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (
c.Set([]byte(sid), data)
c.Expire([]byte(sid), lp.maxlifetime)
}
- return lp.SessionRead(context.Background(), sid)
+ return lp.SessionRead(sid)
}
// SessionDestroy delete ledis session by id
-func (lp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+func (lp *Provider) SessionDestroy(sid string) error {
c.Del([]byte(sid))
return nil
}
// SessionGC Impelment method, no used.
-func (lp *Provider) SessionGC(context.Context) {
+func (lp *Provider) SessionGC() {
}
// SessionAll return all active session
-func (lp *Provider) SessionAll(context.Context) int {
+func (lp *Provider) SessionAll() int {
return 0
}
func init() {
diff --git a/server/web/session/memcache/sess_memcache.go b/session/memcache/sess_memcache.go
similarity index 81%
rename from server/web/session/memcache/sess_memcache.go
rename to session/memcache/sess_memcache.go
index 168116ef..85a2d815 100644
--- a/server/web/session/memcache/sess_memcache.go
+++ b/session/memcache/sess_memcache.go
@@ -33,12 +33,11 @@
package memcache
import (
- "context"
"net/http"
"strings"
"sync"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/astaxie/beego/session"
"github.com/bradfitz/gomemcache/memcache"
)
@@ -55,7 +54,7 @@ type SessionStore struct {
}
// Set value in memcache session
-func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (rs *SessionStore) Set(key, value interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values[key] = value
@@ -63,7 +62,7 @@ func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value in memcache session
-func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (rs *SessionStore) Get(key interface{}) interface{} {
rs.lock.RLock()
defer rs.lock.RUnlock()
if v, ok := rs.values[key]; ok {
@@ -73,7 +72,7 @@ func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in memcache session
-func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (rs *SessionStore) Delete(key interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
delete(rs.values, key)
@@ -81,7 +80,7 @@ func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in memcache session
-func (rs *SessionStore) Flush(context.Context) error {
+func (rs *SessionStore) Flush() error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values = make(map[interface{}]interface{})
@@ -89,12 +88,12 @@ func (rs *SessionStore) Flush(context.Context) error {
}
// SessionID get memcache session id
-func (rs *SessionStore) SessionID(context.Context) string {
+func (rs *SessionStore) SessionID() string {
return rs.sid
}
// SessionRelease save session values to memcache
-func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
if err != nil {
return
@@ -114,7 +113,7 @@ type MemProvider struct {
// SessionInit init memcache session
// savepath like
// e.g. 127.0.0.1:9090
-func (rp *MemProvider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
+func (rp *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
rp.maxlifetime = maxlifetime
rp.conninfo = strings.Split(savePath, ";")
client = memcache.New(rp.conninfo...)
@@ -122,7 +121,7 @@ func (rp *MemProvider) SessionInit(ctx context.Context, maxlifetime int64, saveP
}
// SessionRead read memcache session by sid
-func (rp *MemProvider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (rp *MemProvider) SessionRead(sid string) (session.Store, error) {
if client == nil {
if err := rp.connectInit(); err != nil {
return nil, err
@@ -150,20 +149,20 @@ func (rp *MemProvider) SessionRead(ctx context.Context, sid string) (session.Sto
}
// SessionExist check memcache session exist by sid
-func (rp *MemProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (rp *MemProvider) SessionExist(sid string) bool {
if client == nil {
if err := rp.connectInit(); err != nil {
- return false, err
+ return false
}
}
if item, err := client.Get(sid); err != nil || len(item.Value) == 0 {
- return false, err
+ return false
}
- return true, nil
+ return true
}
// SessionRegenerate generate new sid for memcache session
-func (rp *MemProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
if client == nil {
if err := rp.connectInit(); err != nil {
return nil, err
@@ -202,7 +201,7 @@ func (rp *MemProvider) SessionRegenerate(ctx context.Context, oldsid, sid string
}
// SessionDestroy delete memcache session by id
-func (rp *MemProvider) SessionDestroy(ctx context.Context, sid string) error {
+func (rp *MemProvider) SessionDestroy(sid string) error {
if client == nil {
if err := rp.connectInit(); err != nil {
return err
@@ -218,11 +217,11 @@ func (rp *MemProvider) connectInit() error {
}
// SessionGC Impelment method, no used.
-func (rp *MemProvider) SessionGC(context.Context) {
+func (rp *MemProvider) SessionGC() {
}
// SessionAll return all activeSession
-func (rp *MemProvider) SessionAll(context.Context) int {
+func (rp *MemProvider) SessionAll() int {
return 0
}
diff --git a/server/web/session/mysql/sess_mysql.go b/session/mysql/sess_mysql.go
similarity index 82%
rename from server/web/session/mysql/sess_mysql.go
rename to session/mysql/sess_mysql.go
index 89da361d..301353ab 100644
--- a/server/web/session/mysql/sess_mysql.go
+++ b/session/mysql/sess_mysql.go
@@ -41,13 +41,12 @@
package mysql
import (
- "context"
"database/sql"
"net/http"
"sync"
"time"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/astaxie/beego/session"
// import mysql driver
_ "github.com/go-sql-driver/mysql"
)
@@ -68,7 +67,7 @@ type SessionStore struct {
// Set value in mysql session.
// it is temp value in map.
-func (st *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (st *SessionStore) Set(key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.values[key] = value
@@ -76,7 +75,7 @@ func (st *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value from mysql session
-func (st *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (st *SessionStore) Get(key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.values[key]; ok {
@@ -86,7 +85,7 @@ func (st *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in mysql session
-func (st *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (st *SessionStore) Delete(key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.values, key)
@@ -94,7 +93,7 @@ func (st *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in mysql session
-func (st *SessionStore) Flush(context.Context) error {
+func (st *SessionStore) Flush() error {
st.lock.Lock()
defer st.lock.Unlock()
st.values = make(map[interface{}]interface{})
@@ -102,13 +101,13 @@ func (st *SessionStore) Flush(context.Context) error {
}
// SessionID get session id of this mysql session store
-func (st *SessionStore) SessionID(context.Context) string {
+func (st *SessionStore) SessionID() string {
return st.sid
}
// SessionRelease save mysql session values to database.
// must call this method to save values to database.
-func (st *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
defer st.c.Close()
b, err := session.EncodeGob(st.values)
if err != nil {
@@ -135,14 +134,14 @@ func (mp *Provider) connectInit() *sql.DB {
// SessionInit init mysql session.
// savepath is the connection string of mysql.
-func (mp *Provider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
+func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
mp.maxlifetime = maxlifetime
mp.savePath = savePath
return nil
}
// SessionRead get mysql session by sid
-func (mp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (mp *Provider) SessionRead(sid string) (session.Store, error) {
c := mp.connectInit()
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid)
var sessiondata []byte
@@ -165,23 +164,17 @@ func (mp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist check mysql session exist
-func (mp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (mp *Provider) SessionExist(sid string) bool {
c := mp.connectInit()
defer c.Close()
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid)
var sessiondata []byte
err := row.Scan(&sessiondata)
- if err != nil {
- if err == sql.ErrNoRows {
- return false, nil
- }
- return false, err
- }
- return true, nil
+ return err != sql.ErrNoRows
}
// SessionRegenerate generate new sid for mysql session
-func (mp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
c := mp.connectInit()
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", oldsid)
var sessiondata []byte
@@ -204,7 +197,7 @@ func (mp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (
}
// SessionDestroy delete mysql session by sid
-func (mp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+func (mp *Provider) SessionDestroy(sid string) error {
c := mp.connectInit()
c.Exec("DELETE FROM "+TableName+" where session_key=?", sid)
c.Close()
@@ -212,14 +205,14 @@ func (mp *Provider) SessionDestroy(ctx context.Context, sid string) error {
}
// SessionGC delete expired values in mysql session
-func (mp *Provider) SessionGC(context.Context) {
+func (mp *Provider) SessionGC() {
c := mp.connectInit()
c.Exec("DELETE from "+TableName+" where session_expiry < ?", time.Now().Unix()-mp.maxlifetime)
c.Close()
}
// SessionAll count values in mysql session
-func (mp *Provider) SessionAll(context.Context) int {
+func (mp *Provider) SessionAll() int {
c := mp.connectInit()
defer c.Close()
var total int
diff --git a/server/web/session/postgres/sess_postgresql.go b/session/postgres/sess_postgresql.go
similarity index 83%
rename from server/web/session/postgres/sess_postgresql.go
rename to session/postgres/sess_postgresql.go
index a83ac083..0b8b9645 100644
--- a/server/web/session/postgres/sess_postgresql.go
+++ b/session/postgres/sess_postgresql.go
@@ -51,13 +51,12 @@
package postgres
import (
- "context"
"database/sql"
"net/http"
"sync"
"time"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/astaxie/beego/session"
// import postgresql Driver
_ "github.com/lib/pq"
)
@@ -74,7 +73,7 @@ type SessionStore struct {
// Set value in postgresql session.
// it is temp value in map.
-func (st *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (st *SessionStore) Set(key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.values[key] = value
@@ -82,7 +81,7 @@ func (st *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value from postgresql session
-func (st *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (st *SessionStore) Get(key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.values[key]; ok {
@@ -92,7 +91,7 @@ func (st *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in postgresql session
-func (st *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (st *SessionStore) Delete(key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.values, key)
@@ -100,7 +99,7 @@ func (st *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in postgresql session
-func (st *SessionStore) Flush(context.Context) error {
+func (st *SessionStore) Flush() error {
st.lock.Lock()
defer st.lock.Unlock()
st.values = make(map[interface{}]interface{})
@@ -108,13 +107,13 @@ func (st *SessionStore) Flush(context.Context) error {
}
// SessionID get session id of this postgresql session store
-func (st *SessionStore) SessionID(context.Context) string {
+func (st *SessionStore) SessionID() string {
return st.sid
}
// SessionRelease save postgresql session values to database.
// must call this method to save values to database.
-func (st *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
defer st.c.Close()
b, err := session.EncodeGob(st.values)
if err != nil {
@@ -142,14 +141,14 @@ func (mp *Provider) connectInit() *sql.DB {
// SessionInit init postgresql session.
// savepath is the connection string of postgresql.
-func (mp *Provider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
+func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
mp.maxlifetime = maxlifetime
mp.savePath = savePath
return nil
}
// SessionRead get postgresql session by sid
-func (mp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (mp *Provider) SessionRead(sid string) (session.Store, error) {
c := mp.connectInit()
row := c.QueryRow("select session_data from session where session_key=$1", sid)
var sessiondata []byte
@@ -179,23 +178,17 @@ func (mp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist check postgresql session exist
-func (mp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (mp *Provider) SessionExist(sid string) bool {
c := mp.connectInit()
defer c.Close()
row := c.QueryRow("select session_data from session where session_key=$1", sid)
var sessiondata []byte
err := row.Scan(&sessiondata)
- if err != nil {
- if err == sql.ErrNoRows {
- return false, nil
- }
- return false, err
- }
- return true, nil
+ return err != sql.ErrNoRows
}
// SessionRegenerate generate new sid for postgresql session
-func (mp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
c := mp.connectInit()
row := c.QueryRow("select session_data from session where session_key=$1", oldsid)
var sessiondata []byte
@@ -219,7 +212,7 @@ func (mp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (
}
// SessionDestroy delete postgresql session by sid
-func (mp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+func (mp *Provider) SessionDestroy(sid string) error {
c := mp.connectInit()
c.Exec("DELETE FROM session where session_key=$1", sid)
c.Close()
@@ -227,14 +220,14 @@ func (mp *Provider) SessionDestroy(ctx context.Context, sid string) error {
}
// SessionGC delete expired values in postgresql session
-func (mp *Provider) SessionGC(context.Context) {
+func (mp *Provider) SessionGC() {
c := mp.connectInit()
c.Exec("DELETE from session where EXTRACT(EPOCH FROM (current_timestamp - session_expiry)) > $1", mp.maxlifetime)
c.Close()
}
// SessionAll count values in postgresql session
-func (mp *Provider) SessionAll(context.Context) int {
+func (mp *Provider) SessionAll() int {
c := mp.connectInit()
defer c.Close()
var total int
diff --git a/server/web/session/redis/sess_redis.go b/session/redis/sess_redis.go
similarity index 50%
rename from server/web/session/redis/sess_redis.go
rename to session/redis/sess_redis.go
index c6e3bcbb..5c382d61 100644
--- a/server/web/session/redis/sess_redis.go
+++ b/session/redis/sess_redis.go
@@ -33,17 +33,15 @@
package redis
import (
- "context"
- "encoding/json"
"net/http"
"strconv"
"strings"
"sync"
"time"
- "github.com/go-redis/redis/v7"
+ "github.com/astaxie/beego/session"
- "github.com/astaxie/beego/server/web/session"
+ "github.com/gomodule/redigo/redis"
)
var redispder = &Provider{}
@@ -53,7 +51,7 @@ var MaxPoolSize = 100
// SessionStore redis session store
type SessionStore struct {
- p *redis.Client
+ p *redis.Pool
sid string
lock sync.RWMutex
values map[interface{}]interface{}
@@ -61,7 +59,7 @@ type SessionStore struct {
}
// Set value in redis session
-func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (rs *SessionStore) Set(key, value interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values[key] = value
@@ -69,7 +67,7 @@ func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value in redis session
-func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (rs *SessionStore) Get(key interface{}) interface{} {
rs.lock.RLock()
defer rs.lock.RUnlock()
if v, ok := rs.values[key]; ok {
@@ -79,7 +77,7 @@ func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in redis session
-func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (rs *SessionStore) Delete(key interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
delete(rs.values, key)
@@ -87,7 +85,7 @@ func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in redis session
-func (rs *SessionStore) Flush(context.Context) error {
+func (rs *SessionStore) Flush() error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values = make(map[interface{}]interface{})
@@ -95,132 +93,109 @@ func (rs *SessionStore) Flush(context.Context) error {
}
// SessionID get redis session id
-func (rs *SessionStore) SessionID(context.Context) string {
+func (rs *SessionStore) SessionID() string {
return rs.sid
}
// SessionRelease save session values to redis
-func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
if err != nil {
return
}
- c := rs.p
- c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
+ c := rs.p.Get()
+ defer c.Close()
+ c.Do("SETEX", rs.sid, rs.maxlifetime, string(b))
}
// Provider redis session provider
type Provider struct {
maxlifetime int64
- SavePath string `json:"save_path"`
- Poolsize int `json:"poolsize"`
- Password string `json:"password"`
- DbNum int `json:"db_num"`
-
- idleTimeout time.Duration
- IdleTimeoutStr string `json:"idle_timeout"`
-
- idleCheckFrequency time.Duration
- IdleCheckFrequencyStr string `json:"idle_check_frequency"`
- MaxRetries int `json:"max_retries"`
- poollist *redis.Client
+ savePath string
+ poolsize int
+ password string
+ dbNum int
+ poollist *redis.Pool
}
// SessionInit init redis session
// savepath like redis server addr,pool size,password,dbnum,IdleTimeout second
-// v1.x e.g. 127.0.0.1:6379,100,astaxie,0,30
-// v2.0 you should pass json string
-func (rp *Provider) SessionInit(ctx context.Context, maxlifetime int64, cfgStr string) error {
+// e.g. 127.0.0.1:6379,100,astaxie,0,30
+func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
rp.maxlifetime = maxlifetime
-
- cfgStr = strings.TrimSpace(cfgStr)
- // we think cfgStr is v2.0, using json to init the session
- if strings.HasPrefix(cfgStr, "{") {
- err := json.Unmarshal([]byte(cfgStr), rp)
- if err != nil {
- return err
- }
- rp.idleTimeout, err = time.ParseDuration(rp.IdleTimeoutStr)
- if err != nil {
- return err
- }
-
- rp.idleCheckFrequency, err = time.ParseDuration(rp.IdleCheckFrequencyStr)
- if err != nil {
- return err
- }
-
- } else {
- rp.initOldStyle(cfgStr)
- }
-
- rp.poollist = redis.NewClient(&redis.Options{
- Addr: rp.SavePath,
- Password: rp.Password,
- PoolSize: rp.Poolsize,
- DB: rp.DbNum,
- IdleTimeout: rp.idleTimeout,
- IdleCheckFrequency: rp.idleCheckFrequency,
- MaxRetries: rp.MaxRetries,
- })
-
- return rp.poollist.Ping().Err()
-}
-
-func (rp *Provider) initOldStyle(savePath string) {
configs := strings.Split(savePath, ",")
if len(configs) > 0 {
- rp.SavePath = configs[0]
+ rp.savePath = configs[0]
}
if len(configs) > 1 {
poolsize, err := strconv.Atoi(configs[1])
if err != nil || poolsize < 0 {
- rp.Poolsize = MaxPoolSize
+ rp.poolsize = MaxPoolSize
} else {
- rp.Poolsize = poolsize
+ rp.poolsize = poolsize
}
} else {
- rp.Poolsize = MaxPoolSize
+ rp.poolsize = MaxPoolSize
}
if len(configs) > 2 {
- rp.Password = configs[2]
+ rp.password = configs[2]
}
if len(configs) > 3 {
dbnum, err := strconv.Atoi(configs[3])
if err != nil || dbnum < 0 {
- rp.DbNum = 0
+ rp.dbNum = 0
} else {
- rp.DbNum = dbnum
+ rp.dbNum = dbnum
}
} else {
- rp.DbNum = 0
+ rp.dbNum = 0
}
+ var idleTimeout time.Duration = 0
if len(configs) > 4 {
timeout, err := strconv.Atoi(configs[4])
if err == nil && timeout > 0 {
- rp.idleTimeout = time.Duration(timeout) * time.Second
+ idleTimeout = time.Duration(timeout) * time.Second
}
}
- if len(configs) > 5 {
- checkFrequency, err := strconv.Atoi(configs[5])
- if err == nil && checkFrequency > 0 {
- rp.idleCheckFrequency = time.Duration(checkFrequency) * time.Second
- }
- }
- if len(configs) > 6 {
- retries, err := strconv.Atoi(configs[6])
- if err == nil && retries > 0 {
- rp.MaxRetries = retries
- }
+ rp.poollist = &redis.Pool{
+ Dial: func() (redis.Conn, error) {
+ c, err := redis.Dial("tcp", rp.savePath)
+ if err != nil {
+ return nil, err
+ }
+ if rp.password != "" {
+ if _, err = c.Do("AUTH", rp.password); err != nil {
+ c.Close()
+ return nil, err
+ }
+ }
+ // some redis proxy such as twemproxy is not support select command
+ if rp.dbNum > 0 {
+ _, err = c.Do("SELECT", rp.dbNum)
+ if err != nil {
+ c.Close()
+ return nil, err
+ }
+ }
+ return c, err
+ },
+ MaxIdle: rp.poolsize,
}
+
+ rp.poollist.IdleTimeout = idleTimeout
+
+ return rp.poollist.Get().Err()
}
// SessionRead read redis session by sid
-func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (rp *Provider) SessionRead(sid string) (session.Store, error) {
+ c := rp.poollist.Get()
+ defer c.Close()
+
var kv map[interface{}]interface{}
- kvs, err := rp.poollist.Get(sid).Result()
- if err != nil && err != redis.Nil {
+ kvs, err := redis.String(c.Do("GET", sid))
+ if err != nil && err != redis.ErrNil {
return nil, err
}
if len(kvs) == 0 {
@@ -236,44 +211,48 @@ func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist check redis session exist by sid
-func (rp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
- c := rp.poollist
+func (rp *Provider) SessionExist(sid string) bool {
+ c := rp.poollist.Get()
+ defer c.Close()
- if existed, err := c.Exists(sid).Result(); err != nil || existed == 0 {
- return false, err
+ if existed, err := redis.Int(c.Do("EXISTS", sid)); err != nil || existed == 0 {
+ return false
}
- return true, nil
+ return true
}
// SessionRegenerate generate new sid for redis session
-func (rp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
- c := rp.poollist
- if existed, _ := c.Exists(oldsid).Result(); existed == 0 {
+func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
+ c := rp.poollist.Get()
+ defer c.Close()
+
+ if existed, _ := redis.Int(c.Do("EXISTS", oldsid)); existed == 0 {
// oldsid doesn't exists, set the new sid directly
// ignore error here, since if it return error
// the existed value will be 0
- c.Do(c.Context(), "SET", sid, "", "EX", rp.maxlifetime)
+ c.Do("SET", sid, "", "EX", rp.maxlifetime)
} else {
- c.Rename(oldsid, sid)
- c.Expire(sid, time.Duration(rp.maxlifetime)*time.Second)
+ c.Do("RENAME", oldsid, sid)
+ c.Do("EXPIRE", sid, rp.maxlifetime)
}
- return rp.SessionRead(context.Background(), sid)
+ return rp.SessionRead(sid)
}
// SessionDestroy delete redis session by id
-func (rp *Provider) SessionDestroy(ctx context.Context, sid string) error {
- c := rp.poollist
+func (rp *Provider) SessionDestroy(sid string) error {
+ c := rp.poollist.Get()
+ defer c.Close()
- c.Del(sid)
+ c.Do("DEL", sid)
return nil
}
// SessionGC Impelment method, no used.
-func (rp *Provider) SessionGC(context.Context) {
+func (rp *Provider) SessionGC() {
}
// SessionAll return all activeSession
-func (rp *Provider) SessionAll(context.Context) int {
+func (rp *Provider) SessionAll() int {
return 0
}
diff --git a/server/web/session/redis_cluster/redis_cluster.go b/session/redis_cluster/redis_cluster.go
similarity index 55%
rename from server/web/session/redis_cluster/redis_cluster.go
rename to session/redis_cluster/redis_cluster.go
index d2971e71..2fe300df 100644
--- a/server/web/session/redis_cluster/redis_cluster.go
+++ b/session/redis_cluster/redis_cluster.go
@@ -31,19 +31,14 @@
//
// more docs: http://beego.me/docs/module/session.md
package redis_cluster
-
import (
- "context"
- "encoding/json"
"net/http"
"strconv"
"strings"
"sync"
+ "github.com/astaxie/beego/session"
+ rediss "github.com/go-redis/redis"
"time"
-
- rediss "github.com/go-redis/redis/v7"
-
- "github.com/astaxie/beego/server/web/session"
)
var redispder = &Provider{}
@@ -61,7 +56,7 @@ type SessionStore struct {
}
// Set value in redis_cluster session
-func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (rs *SessionStore) Set(key, value interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values[key] = value
@@ -69,7 +64,7 @@ func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value in redis_cluster session
-func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (rs *SessionStore) Get(key interface{}) interface{} {
rs.lock.RLock()
defer rs.lock.RUnlock()
if v, ok := rs.values[key]; ok {
@@ -79,7 +74,7 @@ func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in redis_cluster session
-func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (rs *SessionStore) Delete(key interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
delete(rs.values, key)
@@ -87,7 +82,7 @@ func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in redis_cluster session
-func (rs *SessionStore) Flush(context.Context) error {
+func (rs *SessionStore) Flush() error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values = make(map[interface{}]interface{})
@@ -95,125 +90,73 @@ func (rs *SessionStore) Flush(context.Context) error {
}
// SessionID get redis_cluster session id
-func (rs *SessionStore) SessionID(context.Context) string {
+func (rs *SessionStore) SessionID() string {
return rs.sid
}
// SessionRelease save session values to redis_cluster
-func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
if err != nil {
return
}
c := rs.p
- c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
+ c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime) * time.Second)
}
// Provider redis_cluster session provider
type Provider struct {
maxlifetime int64
- SavePath string `json:"save_path"`
- Poolsize int `json:"poolsize"`
- Password string `json:"password"`
- DbNum int `json:"db_num"`
-
- idleTimeout time.Duration
- IdleTimeoutStr string `json:"idle_timeout"`
-
- idleCheckFrequency time.Duration
- IdleCheckFrequencyStr string `json:"idle_check_frequency"`
- MaxRetries int `json:"max_retries"`
- poollist *rediss.ClusterClient
+ savePath string
+ poolsize int
+ password string
+ dbNum int
+ poollist *rediss.ClusterClient
}
// SessionInit init redis_cluster session
-// cfgStr like redis server addr,pool size,password,dbnum
+// savepath like redis server addr,pool size,password,dbnum
// e.g. 127.0.0.1:6379;127.0.0.1:6380,100,test,0
-func (rp *Provider) SessionInit(ctx context.Context, maxlifetime int64, cfgStr string) error {
+func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
rp.maxlifetime = maxlifetime
- cfgStr = strings.TrimSpace(cfgStr)
- // we think cfgStr is v2.0, using json to init the session
- if strings.HasPrefix(cfgStr, "{") {
- err := json.Unmarshal([]byte(cfgStr), rp)
- if err != nil {
- return err
- }
- rp.idleTimeout, err = time.ParseDuration(rp.IdleTimeoutStr)
- if err != nil {
- return err
- }
-
- rp.idleCheckFrequency, err = time.ParseDuration(rp.IdleCheckFrequencyStr)
- if err != nil {
- return err
- }
-
- } else {
- rp.initOldStyle(cfgStr)
- }
-
- rp.poollist = rediss.NewClusterClient(&rediss.ClusterOptions{
- Addrs: strings.Split(rp.SavePath, ";"),
- Password: rp.Password,
- PoolSize: rp.Poolsize,
- IdleTimeout: rp.idleTimeout,
- IdleCheckFrequency: rp.idleCheckFrequency,
- MaxRetries: rp.MaxRetries,
- })
- return rp.poollist.Ping().Err()
-}
-
-// for v1.x
-func (rp *Provider) initOldStyle(savePath string) {
configs := strings.Split(savePath, ",")
if len(configs) > 0 {
- rp.SavePath = configs[0]
+ rp.savePath = configs[0]
}
if len(configs) > 1 {
poolsize, err := strconv.Atoi(configs[1])
if err != nil || poolsize < 0 {
- rp.Poolsize = MaxPoolSize
+ rp.poolsize = MaxPoolSize
} else {
- rp.Poolsize = poolsize
+ rp.poolsize = poolsize
}
} else {
- rp.Poolsize = MaxPoolSize
+ rp.poolsize = MaxPoolSize
}
if len(configs) > 2 {
- rp.Password = configs[2]
+ rp.password = configs[2]
}
if len(configs) > 3 {
dbnum, err := strconv.Atoi(configs[3])
if err != nil || dbnum < 0 {
- rp.DbNum = 0
+ rp.dbNum = 0
} else {
- rp.DbNum = dbnum
+ rp.dbNum = dbnum
}
} else {
- rp.DbNum = 0
- }
- if len(configs) > 4 {
- timeout, err := strconv.Atoi(configs[4])
- if err == nil && timeout > 0 {
- rp.idleTimeout = time.Duration(timeout) * time.Second
- }
- }
- if len(configs) > 5 {
- checkFrequency, err := strconv.Atoi(configs[5])
- if err == nil && checkFrequency > 0 {
- rp.idleCheckFrequency = time.Duration(checkFrequency) * time.Second
- }
- }
- if len(configs) > 6 {
- retries, err := strconv.Atoi(configs[6])
- if err == nil && retries > 0 {
- rp.MaxRetries = retries
- }
+ rp.dbNum = 0
}
+
+ rp.poollist = rediss.NewClusterClient(&rediss.ClusterOptions{
+ Addrs: strings.Split(rp.savePath, ";"),
+ Password: rp.password,
+ PoolSize: rp.poolsize,
+ })
+ return rp.poollist.Ping().Err()
}
// SessionRead read redis_cluster session by sid
-func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (rp *Provider) SessionRead(sid string) (session.Store, error) {
var kv map[interface{}]interface{}
kvs, err := rp.poollist.Get(sid).Result()
if err != nil && err != rediss.Nil {
@@ -232,43 +175,43 @@ func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist check redis_cluster session exist by sid
-func (rp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (rp *Provider) SessionExist(sid string) bool {
c := rp.poollist
if existed, err := c.Exists(sid).Result(); err != nil || existed == 0 {
- return false, err
+ return false
}
- return true, nil
+ return true
}
// SessionRegenerate generate new sid for redis_cluster session
-func (rp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
c := rp.poollist
-
+
if existed, err := c.Exists(oldsid).Result(); err != nil || existed == 0 {
// oldsid doesn't exists, set the new sid directly
// ignore error here, since if it return error
// the existed value will be 0
- c.Set(sid, "", time.Duration(rp.maxlifetime)*time.Second)
+ c.Set(sid, "", time.Duration(rp.maxlifetime) * time.Second)
} else {
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(context.Background(), sid)
+ return rp.SessionRead(sid)
}
// SessionDestroy delete redis session by id
-func (rp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+func (rp *Provider) SessionDestroy(sid string) error {
c := rp.poollist
c.Del(sid)
return nil
}
// SessionGC Impelment method, no used.
-func (rp *Provider) SessionGC(context.Context) {
+func (rp *Provider) SessionGC() {
}
// SessionAll return all activeSession
-func (rp *Provider) SessionAll(context.Context) int {
+func (rp *Provider) SessionAll() int {
return 0
}
diff --git a/server/web/session/redis_sentinel/sess_redis_sentinel.go b/session/redis_sentinel/sess_redis_sentinel.go
similarity index 57%
rename from server/web/session/redis_sentinel/sess_redis_sentinel.go
rename to session/redis_sentinel/sess_redis_sentinel.go
index 89d73b86..6ecb2977 100644
--- a/server/web/session/redis_sentinel/sess_redis_sentinel.go
+++ b/session/redis_sentinel/sess_redis_sentinel.go
@@ -33,17 +33,13 @@
package redis_sentinel
import (
- "context"
- "encoding/json"
+ "github.com/astaxie/beego/session"
+ "github.com/go-redis/redis"
"net/http"
"strconv"
"strings"
"sync"
"time"
-
- "github.com/go-redis/redis/v7"
-
- "github.com/astaxie/beego/server/web/session"
)
var redispder = &Provider{}
@@ -61,7 +57,7 @@ type SessionStore struct {
}
// Set value in redis_sentinel session
-func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (rs *SessionStore) Set(key, value interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values[key] = value
@@ -69,7 +65,7 @@ func (rs *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get value in redis_sentinel session
-func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (rs *SessionStore) Get(key interface{}) interface{} {
rs.lock.RLock()
defer rs.lock.RUnlock()
if v, ok := rs.values[key]; ok {
@@ -79,7 +75,7 @@ func (rs *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete value in redis_sentinel session
-func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (rs *SessionStore) Delete(key interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
delete(rs.values, key)
@@ -87,7 +83,7 @@ func (rs *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in redis_sentinel session
-func (rs *SessionStore) Flush(context.Context) error {
+func (rs *SessionStore) Flush() error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values = make(map[interface{}]interface{})
@@ -95,12 +91,12 @@ func (rs *SessionStore) Flush(context.Context) error {
}
// SessionID get redis_sentinel session id
-func (rs *SessionStore) SessionID(context.Context) string {
+func (rs *SessionStore) SessionID() string {
return rs.sid
}
// SessionRelease save session values to redis_sentinel
-func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
if err != nil {
return
@@ -112,121 +108,69 @@ func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWrite
// Provider redis_sentinel session provider
type Provider struct {
maxlifetime int64
- SavePath string `json:"save_path"`
- Poolsize int `json:"poolsize"`
- Password string `json:"password"`
- DbNum int `json:"db_num"`
-
- idleTimeout time.Duration
- IdleTimeoutStr string `json:"idle_timeout"`
-
- idleCheckFrequency time.Duration
- IdleCheckFrequencyStr string `json:"idle_check_frequency"`
- MaxRetries int `json:"max_retries"`
- poollist *redis.Client
- MasterName string `json:"master_name"`
+ savePath string
+ poolsize int
+ password string
+ dbNum int
+ poollist *redis.Client
+ masterName string
}
// SessionInit init redis_sentinel session
-// cfgStr like redis sentinel addr,pool size,password,dbnum,masterName
+// savepath like redis sentinel addr,pool size,password,dbnum,masterName
// e.g. 127.0.0.1:26379;127.0.0.2:26379,100,1qaz2wsx,0,mymaster
-func (rp *Provider) SessionInit(ctx context.Context, maxlifetime int64, cfgStr string) error {
+func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
rp.maxlifetime = maxlifetime
- cfgStr = strings.TrimSpace(cfgStr)
- // we think cfgStr is v2.0, using json to init the session
- if strings.HasPrefix(cfgStr, "{") {
- err := json.Unmarshal([]byte(cfgStr), rp)
- if err != nil {
- return err
+ configs := strings.Split(savePath, ",")
+ if len(configs) > 0 {
+ rp.savePath = configs[0]
+ }
+ if len(configs) > 1 {
+ poolsize, err := strconv.Atoi(configs[1])
+ if err != nil || poolsize < 0 {
+ rp.poolsize = DefaultPoolSize
+ } else {
+ rp.poolsize = poolsize
}
- rp.idleTimeout, err = time.ParseDuration(rp.IdleTimeoutStr)
- if err != nil {
- return err
- }
-
- rp.idleCheckFrequency, err = time.ParseDuration(rp.IdleCheckFrequencyStr)
- if err != nil {
- return err
- }
-
} else {
- rp.initOldStyle(cfgStr)
+ rp.poolsize = DefaultPoolSize
+ }
+ if len(configs) > 2 {
+ rp.password = configs[2]
+ }
+ if len(configs) > 3 {
+ dbnum, err := strconv.Atoi(configs[3])
+ if err != nil || dbnum < 0 {
+ rp.dbNum = 0
+ } else {
+ rp.dbNum = dbnum
+ }
+ } else {
+ rp.dbNum = 0
+ }
+ if len(configs) > 4 {
+ if configs[4] != "" {
+ rp.masterName = configs[4]
+ } else {
+ rp.masterName = "mymaster"
+ }
+ } else {
+ rp.masterName = "mymaster"
}
rp.poollist = redis.NewFailoverClient(&redis.FailoverOptions{
- SentinelAddrs: strings.Split(rp.SavePath, ";"),
- Password: rp.Password,
- PoolSize: rp.Poolsize,
- DB: rp.DbNum,
- MasterName: rp.MasterName,
- IdleTimeout: rp.idleTimeout,
- IdleCheckFrequency: rp.idleCheckFrequency,
- MaxRetries: rp.MaxRetries,
+ SentinelAddrs: strings.Split(rp.savePath, ";"),
+ Password: rp.password,
+ PoolSize: rp.poolsize,
+ DB: rp.dbNum,
+ MasterName: rp.masterName,
})
return rp.poollist.Ping().Err()
}
-// for v1.x
-func (rp *Provider) initOldStyle(savePath string) {
- configs := strings.Split(savePath, ",")
- if len(configs) > 0 {
- rp.SavePath = configs[0]
- }
- if len(configs) > 1 {
- poolsize, err := strconv.Atoi(configs[1])
- if err != nil || poolsize < 0 {
- rp.Poolsize = DefaultPoolSize
- } else {
- rp.Poolsize = poolsize
- }
- } else {
- rp.Poolsize = DefaultPoolSize
- }
- if len(configs) > 2 {
- rp.Password = configs[2]
- }
- if len(configs) > 3 {
- dbnum, err := strconv.Atoi(configs[3])
- if err != nil || dbnum < 0 {
- rp.DbNum = 0
- } else {
- rp.DbNum = dbnum
- }
- } else {
- rp.DbNum = 0
- }
- if len(configs) > 4 {
- if configs[4] != "" {
- rp.MasterName = configs[4]
- } else {
- rp.MasterName = "mymaster"
- }
- } else {
- rp.MasterName = "mymaster"
- }
- if len(configs) > 5 {
- timeout, err := strconv.Atoi(configs[4])
- if err == nil && timeout > 0 {
- rp.idleTimeout = time.Duration(timeout) * time.Second
- }
- }
- if len(configs) > 6 {
- checkFrequency, err := strconv.Atoi(configs[5])
- if err == nil && checkFrequency > 0 {
- rp.idleCheckFrequency = time.Duration(checkFrequency) * time.Second
- }
- }
- if len(configs) > 7 {
- retries, err := strconv.Atoi(configs[6])
- if err == nil && retries > 0 {
- rp.MaxRetries = retries
- }
- }
-}
-
// SessionRead read redis_sentinel session by sid
-func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (rp *Provider) SessionRead(sid string) (session.Store, error) {
var kv map[interface{}]interface{}
kvs, err := rp.poollist.Get(sid).Result()
if err != nil && err != redis.Nil {
@@ -245,16 +189,16 @@ func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist check redis_sentinel session exist by sid
-func (rp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (rp *Provider) SessionExist(sid string) bool {
c := rp.poollist
if existed, err := c.Exists(sid).Result(); err != nil || existed == 0 {
- return false, err
+ return false
}
- return true, nil
+ return true
}
// SessionRegenerate generate new sid for redis_sentinel session
-func (rp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
c := rp.poollist
if existed, err := c.Exists(oldsid).Result(); err != nil || existed == 0 {
@@ -266,22 +210,22 @@ func (rp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (
c.Rename(oldsid, sid)
c.Expire(sid, time.Duration(rp.maxlifetime)*time.Second)
}
- return rp.SessionRead(context.Background(), sid)
+ return rp.SessionRead(sid)
}
// SessionDestroy delete redis session by id
-func (rp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+func (rp *Provider) SessionDestroy(sid string) error {
c := rp.poollist
c.Del(sid)
return nil
}
// SessionGC Impelment method, no used.
-func (rp *Provider) SessionGC(context.Context) {
+func (rp *Provider) SessionGC() {
}
// SessionAll return all activeSession
-func (rp *Provider) SessionAll(context.Context) int {
+func (rp *Provider) SessionAll() int {
return 0
}
diff --git a/adapter/session/redis_sentinel/sess_redis_sentinel_test.go b/session/redis_sentinel/sess_redis_sentinel_test.go
similarity index 96%
rename from adapter/session/redis_sentinel/sess_redis_sentinel_test.go
rename to session/redis_sentinel/sess_redis_sentinel_test.go
index 407d32ab..fd4155c6 100644
--- a/adapter/session/redis_sentinel/sess_redis_sentinel_test.go
+++ b/session/redis_sentinel/sess_redis_sentinel_test.go
@@ -5,7 +5,7 @@ import (
"net/http/httptest"
"testing"
- "github.com/astaxie/beego/adapter/session"
+ "github.com/astaxie/beego/session"
)
func TestRedisSentinel(t *testing.T) {
@@ -23,7 +23,7 @@ func TestRedisSentinel(t *testing.T) {
t.Log(e)
return
}
- // todo test if e==nil
+ //todo test if e==nil
go globalSessions.GC()
r, _ := http.NewRequest("GET", "/", nil)
diff --git a/server/web/session/sess_cookie.go b/session/sess_cookie.go
similarity index 77%
rename from server/web/session/sess_cookie.go
rename to session/sess_cookie.go
index 649f6510..6ad5debc 100644
--- a/server/web/session/sess_cookie.go
+++ b/session/sess_cookie.go
@@ -15,7 +15,6 @@
package session
import (
- "context"
"crypto/aes"
"crypto/cipher"
"encoding/json"
@@ -35,7 +34,7 @@ type CookieSessionStore struct {
// Set value to cookie session.
// the value are encoded as gob with hash block string.
-func (st *CookieSessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (st *CookieSessionStore) Set(key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.values[key] = value
@@ -43,7 +42,7 @@ func (st *CookieSessionStore) Set(ctx context.Context, key, value interface{}) e
}
// Get value from cookie session
-func (st *CookieSessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (st *CookieSessionStore) Get(key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.values[key]; ok {
@@ -53,7 +52,7 @@ func (st *CookieSessionStore) Get(ctx context.Context, key interface{}) interfac
}
// Delete value in cookie session
-func (st *CookieSessionStore) Delete(ctx context.Context, key interface{}) error {
+func (st *CookieSessionStore) Delete(key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.values, key)
@@ -61,7 +60,7 @@ func (st *CookieSessionStore) Delete(ctx context.Context, key interface{}) error
}
// Flush Clean all values in cookie session
-func (st *CookieSessionStore) Flush(context.Context) error {
+func (st *CookieSessionStore) Flush() error {
st.lock.Lock()
defer st.lock.Unlock()
st.values = make(map[interface{}]interface{})
@@ -69,12 +68,12 @@ func (st *CookieSessionStore) Flush(context.Context) error {
}
// SessionID Return id of this cookie session
-func (st *CookieSessionStore) SessionID(context.Context) string {
+func (st *CookieSessionStore) SessionID() string {
return st.sid
}
// SessionRelease Write cookie session to http response cookie
-func (st *CookieSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
st.lock.Lock()
encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values)
st.lock.Unlock()
@@ -113,7 +112,7 @@ type CookieProvider struct {
// securityName - recognized name in encoded cookie string
// cookieName - cookie name
// maxage - cookie max life time.
-func (pder *CookieProvider) SessionInit(ctx context.Context, maxlifetime int64, config string) error {
+func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error {
pder.config = &cookieConfig{}
err := json.Unmarshal([]byte(config), pder.config)
if err != nil {
@@ -135,7 +134,7 @@ func (pder *CookieProvider) SessionInit(ctx context.Context, maxlifetime int64,
// SessionRead Get SessionStore in cooke.
// decode cooke string to map and put into SessionStore with sid.
-func (pder *CookieProvider) SessionRead(ctx context.Context, sid string) (Store, error) {
+func (pder *CookieProvider) SessionRead(sid string) (Store, error) {
maps, _ := decodeCookie(pder.block,
pder.config.SecurityKey,
pder.config.SecurityName,
@@ -148,31 +147,31 @@ func (pder *CookieProvider) SessionRead(ctx context.Context, sid string) (Store,
}
// SessionExist Cookie session is always existed
-func (pder *CookieProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
- return true, nil
+func (pder *CookieProvider) SessionExist(sid string) bool {
+ return true
}
// SessionRegenerate Implement method, no used.
-func (pder *CookieProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
+func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
return nil, nil
}
// SessionDestroy Implement method, no used.
-func (pder *CookieProvider) SessionDestroy(ctx context.Context, sid string) error {
+func (pder *CookieProvider) SessionDestroy(sid string) error {
return nil
}
// SessionGC Implement method, no used.
-func (pder *CookieProvider) SessionGC(context.Context) {
+func (pder *CookieProvider) SessionGC() {
}
// SessionAll Implement method, return 0.
-func (pder *CookieProvider) SessionAll(context.Context) int {
+func (pder *CookieProvider) SessionAll() int {
return 0
}
// SessionUpdate Implement method, no used.
-func (pder *CookieProvider) SessionUpdate(ctx context.Context, sid string) error {
+func (pder *CookieProvider) SessionUpdate(sid string) error {
return nil
}
diff --git a/adapter/session/sess_cookie_test.go b/session/sess_cookie_test.go
similarity index 100%
rename from adapter/session/sess_cookie_test.go
rename to session/sess_cookie_test.go
diff --git a/server/web/session/sess_file.go b/session/sess_file.go
similarity index 85%
rename from server/web/session/sess_file.go
rename to session/sess_file.go
index 90de9a79..c6dbf209 100644
--- a/server/web/session/sess_file.go
+++ b/session/sess_file.go
@@ -15,12 +15,11 @@
package session
import (
- "context"
- "errors"
"fmt"
"io/ioutil"
"net/http"
"os"
+ "errors"
"path"
"path/filepath"
"strings"
@@ -41,7 +40,7 @@ type FileSessionStore struct {
}
// Set value to file session
-func (fs *FileSessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (fs *FileSessionStore) Set(key, value interface{}) error {
fs.lock.Lock()
defer fs.lock.Unlock()
fs.values[key] = value
@@ -49,7 +48,7 @@ func (fs *FileSessionStore) Set(ctx context.Context, key, value interface{}) err
}
// Get value from file session
-func (fs *FileSessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (fs *FileSessionStore) Get(key interface{}) interface{} {
fs.lock.RLock()
defer fs.lock.RUnlock()
if v, ok := fs.values[key]; ok {
@@ -59,7 +58,7 @@ func (fs *FileSessionStore) Get(ctx context.Context, key interface{}) interface{
}
// Delete value in file session by given key
-func (fs *FileSessionStore) Delete(ctx context.Context, key interface{}) error {
+func (fs *FileSessionStore) Delete(key interface{}) error {
fs.lock.Lock()
defer fs.lock.Unlock()
delete(fs.values, key)
@@ -67,7 +66,7 @@ func (fs *FileSessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush Clean all values in file session
-func (fs *FileSessionStore) Flush(context.Context) error {
+func (fs *FileSessionStore) Flush() error {
fs.lock.Lock()
defer fs.lock.Unlock()
fs.values = make(map[interface{}]interface{})
@@ -75,12 +74,12 @@ func (fs *FileSessionStore) Flush(context.Context) error {
}
// SessionID Get file session store id
-func (fs *FileSessionStore) SessionID(context.Context) string {
+func (fs *FileSessionStore) SessionID() string {
return fs.sid
}
// SessionRelease Write file session to local file with Gob string
-func (fs *FileSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
b, err := EncodeGob(fs.values)
@@ -120,7 +119,7 @@ type FileProvider struct {
// SessionInit Init file session provider.
// savePath sets the session files path.
-func (fp *FileProvider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
+func (fp *FileProvider) SessionInit(maxlifetime int64, savePath string) error {
fp.maxlifetime = maxlifetime
fp.savePath = savePath
return nil
@@ -129,7 +128,7 @@ func (fp *FileProvider) SessionInit(ctx context.Context, maxlifetime int64, save
// SessionRead Read file session by sid.
// if file is not exist, create it.
// the file path is generated from sid string.
-func (fp *FileProvider) SessionRead(ctx context.Context, sid string) (Store, error) {
+func (fp *FileProvider) SessionRead(sid string) (Store, error) {
invalidChars := "./"
if strings.ContainsAny(sid, invalidChars) {
return nil, errors.New("the sid shouldn't have following characters: " + invalidChars)
@@ -177,21 +176,16 @@ func (fp *FileProvider) SessionRead(ctx context.Context, sid string) (Store, err
// SessionExist Check file session exist.
// it checks the file named from sid exist or not.
-func (fp *FileProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (fp *FileProvider) SessionExist(sid string) bool {
filepder.lock.Lock()
defer filepder.lock.Unlock()
- if len(sid) < 2 {
- SLogger.Println("min length of session id is 2 but got length: ", sid)
- return false, errors.New("min length of session id is 2")
- }
-
_, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
- return err == nil, nil
+ return err == nil
}
// SessionDestroy Remove all files in this save path
-func (fp *FileProvider) SessionDestroy(ctx context.Context, sid string) error {
+func (fp *FileProvider) SessionDestroy(sid string) error {
filepder.lock.Lock()
defer filepder.lock.Unlock()
os.Remove(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
@@ -199,7 +193,7 @@ func (fp *FileProvider) SessionDestroy(ctx context.Context, sid string) error {
}
// SessionGC Recycle files in save path
-func (fp *FileProvider) SessionGC(context.Context) {
+func (fp *FileProvider) SessionGC() {
filepder.lock.Lock()
defer filepder.lock.Unlock()
@@ -209,7 +203,7 @@ func (fp *FileProvider) SessionGC(context.Context) {
// SessionAll Get active file session number.
// it walks save path to count files.
-func (fp *FileProvider) SessionAll(context.Context) int {
+func (fp *FileProvider) SessionAll() int {
a := &activeSession{}
err := filepath.Walk(fp.savePath, func(path string, f os.FileInfo, err error) error {
return a.visit(path, f, err)
@@ -223,7 +217,7 @@ func (fp *FileProvider) SessionAll(context.Context) int {
// SessionRegenerate Generate new sid for file session.
// it delete old file and create new file named from new sid.
-func (fp *FileProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
+func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
diff --git a/server/web/session/sess_mem.go b/session/sess_mem.go
similarity index 78%
rename from server/web/session/sess_mem.go
rename to session/sess_mem.go
index 27e24c73..64d8b056 100644
--- a/server/web/session/sess_mem.go
+++ b/session/sess_mem.go
@@ -16,7 +16,6 @@ package session
import (
"container/list"
- "context"
"net/http"
"sync"
"time"
@@ -34,7 +33,7 @@ type MemSessionStore struct {
}
// Set value to memory session
-func (st *MemSessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (st *MemSessionStore) Set(key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.value[key] = value
@@ -42,7 +41,7 @@ func (st *MemSessionStore) Set(ctx context.Context, key, value interface{}) erro
}
// Get value from memory session by key
-func (st *MemSessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (st *MemSessionStore) Get(key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.value[key]; ok {
@@ -52,7 +51,7 @@ func (st *MemSessionStore) Get(ctx context.Context, key interface{}) interface{}
}
// Delete in memory session by key
-func (st *MemSessionStore) Delete(ctx context.Context, key interface{}) error {
+func (st *MemSessionStore) Delete(key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.value, key)
@@ -60,7 +59,7 @@ func (st *MemSessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush clear all values in memory session
-func (st *MemSessionStore) Flush(context.Context) error {
+func (st *MemSessionStore) Flush() error {
st.lock.Lock()
defer st.lock.Unlock()
st.value = make(map[interface{}]interface{})
@@ -68,12 +67,12 @@ func (st *MemSessionStore) Flush(context.Context) error {
}
// SessionID get this id of memory session store
-func (st *MemSessionStore) SessionID(context.Context) string {
+func (st *MemSessionStore) SessionID() string {
return st.sid
}
// SessionRelease Implement method, no used.
-func (st *MemSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (st *MemSessionStore) SessionRelease(w http.ResponseWriter) {
}
// MemProvider Implement the provider interface
@@ -86,17 +85,17 @@ type MemProvider struct {
}
// SessionInit init memory session
-func (pder *MemProvider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
+func (pder *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
pder.maxlifetime = maxlifetime
pder.savePath = savePath
return nil
}
// SessionRead get memory session store by sid
-func (pder *MemProvider) SessionRead(ctx context.Context, sid string) (Store, error) {
+func (pder *MemProvider) SessionRead(sid string) (Store, error) {
pder.lock.RLock()
if element, ok := pder.sessions[sid]; ok {
- go pder.SessionUpdate(nil, sid)
+ go pder.SessionUpdate(sid)
pder.lock.RUnlock()
return element.Value.(*MemSessionStore), nil
}
@@ -110,20 +109,20 @@ func (pder *MemProvider) SessionRead(ctx context.Context, sid string) (Store, er
}
// SessionExist check session store exist in memory session by sid
-func (pder *MemProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (pder *MemProvider) SessionExist(sid string) bool {
pder.lock.RLock()
defer pder.lock.RUnlock()
if _, ok := pder.sessions[sid]; ok {
- return true, nil
+ return true
}
- return false, nil
+ return false
}
// SessionRegenerate generate new sid for session store in memory session
-func (pder *MemProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
+func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
pder.lock.RLock()
if element, ok := pder.sessions[oldsid]; ok {
- go pder.SessionUpdate(nil, oldsid)
+ go pder.SessionUpdate(oldsid)
pder.lock.RUnlock()
pder.lock.Lock()
element.Value.(*MemSessionStore).sid = sid
@@ -142,7 +141,7 @@ func (pder *MemProvider) SessionRegenerate(ctx context.Context, oldsid, sid stri
}
// SessionDestroy delete session store in memory session by id
-func (pder *MemProvider) SessionDestroy(ctx context.Context, sid string) error {
+func (pder *MemProvider) SessionDestroy(sid string) error {
pder.lock.Lock()
defer pder.lock.Unlock()
if element, ok := pder.sessions[sid]; ok {
@@ -154,7 +153,7 @@ func (pder *MemProvider) SessionDestroy(ctx context.Context, sid string) error {
}
// SessionGC clean expired session stores in memory session
-func (pder *MemProvider) SessionGC(context.Context) {
+func (pder *MemProvider) SessionGC() {
pder.lock.RLock()
for {
element := pder.list.Back()
@@ -176,12 +175,12 @@ func (pder *MemProvider) SessionGC(context.Context) {
}
// SessionAll get count number of memory session
-func (pder *MemProvider) SessionAll(context.Context) int {
+func (pder *MemProvider) SessionAll() int {
return pder.list.Len()
}
// SessionUpdate expand time of session store by id in memory session
-func (pder *MemProvider) SessionUpdate(ctx context.Context, sid string) error {
+func (pder *MemProvider) SessionUpdate(sid string) error {
pder.lock.Lock()
defer pder.lock.Unlock()
if element, ok := pder.sessions[sid]; ok {
diff --git a/adapter/session/sess_mem_test.go b/session/sess_mem_test.go
similarity index 100%
rename from adapter/session/sess_mem_test.go
rename to session/sess_mem_test.go
diff --git a/server/web/session/sess_test.go b/session/sess_test.go
similarity index 100%
rename from server/web/session/sess_test.go
rename to session/sess_test.go
diff --git a/server/web/session/sess_utils.go b/session/sess_utils.go
similarity index 99%
rename from server/web/session/sess_utils.go
rename to session/sess_utils.go
index 8a031dd5..20915bb6 100644
--- a/server/web/session/sess_utils.go
+++ b/session/sess_utils.go
@@ -29,7 +29,7 @@ import (
"strconv"
"time"
- "github.com/astaxie/beego/core/utils"
+ "github.com/astaxie/beego/utils"
)
func init() {
diff --git a/server/web/session/session.go b/session/session.go
similarity index 86%
rename from server/web/session/session.go
rename to session/session.go
index bb7e5bd6..eb85360a 100644
--- a/server/web/session/session.go
+++ b/session/session.go
@@ -28,7 +28,6 @@
package session
import (
- "context"
"crypto/rand"
"encoding/hex"
"errors"
@@ -44,24 +43,24 @@ import (
// Store contains all data for one session process with specific id.
type Store interface {
- Set(ctx context.Context, key, value interface{}) error //set session value
- Get(ctx context.Context, key interface{}) interface{} //get session value
- Delete(ctx context.Context, key interface{}) error //delete session value
- SessionID(ctx context.Context) string //back current sessionID
- SessionRelease(ctx context.Context, w http.ResponseWriter) // release the resource & save data to provider & return the data
- Flush(ctx context.Context) error //delete all data
+ Set(key, value interface{}) error //set session value
+ Get(key interface{}) interface{} //get session value
+ Delete(key interface{}) error //delete session value
+ SessionID() string //back current sessionID
+ SessionRelease(w http.ResponseWriter) // release the resource & save data to provider & return the data
+ Flush() error //delete all data
}
// Provider contains global session methods and saved SessionStores.
// it can operate a SessionStore by its id.
type Provider interface {
- SessionInit(ctx context.Context, gclifetime int64, config string) error
- SessionRead(ctx context.Context, sid string) (Store, error)
- SessionExist(ctx context.Context, sid string) (bool, error)
- SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error)
- SessionDestroy(ctx context.Context, sid string) error
- SessionAll(ctx context.Context) int //get all active session
- SessionGC(ctx context.Context)
+ SessionInit(gclifetime int64, config string) error
+ SessionRead(sid string) (Store, error)
+ SessionExist(sid string) bool
+ SessionRegenerate(oldsid, sid string) (Store, error)
+ SessionDestroy(sid string) error
+ SessionAll() int //get all active session
+ SessionGC()
}
var provides = make(map[string]Provider)
@@ -149,7 +148,7 @@ func NewManager(provideName string, cf *ManagerConfig) (*Manager, error) {
}
}
- err := provider.SessionInit(nil, cf.Maxlifetime, cf.ProviderConfig)
+ err := provider.SessionInit(cf.Maxlifetime, cf.ProviderConfig)
if err != nil {
return nil, err
}
@@ -212,14 +211,8 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
return nil, errs
}
- if sid != "" {
- exists, err := manager.provider.SessionExist(nil, sid)
- if err != nil {
- return nil, err
- }
- if exists {
- return manager.provider.SessionRead(nil, sid)
- }
+ if sid != "" && manager.provider.SessionExist(sid) {
+ return manager.provider.SessionRead(sid)
}
// Generate a new session
@@ -228,7 +221,7 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
return nil, errs
}
- session, err = manager.provider.SessionRead(nil, sid)
+ session, err = manager.provider.SessionRead(sid)
if err != nil {
return nil, err
}
@@ -270,7 +263,7 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
}
sid, _ := url.QueryUnescape(cookie.Value)
- manager.provider.SessionDestroy(nil, sid)
+ manager.provider.SessionDestroy(sid)
if manager.config.EnableSetCookie {
expiration := time.Now()
cookie = &http.Cookie{Name: manager.config.CookieName,
@@ -286,14 +279,14 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
// GetSessionStore Get SessionStore by its id.
func (manager *Manager) GetSessionStore(sid string) (sessions Store, err error) {
- sessions, err = manager.provider.SessionRead(nil, sid)
+ sessions, err = manager.provider.SessionRead(sid)
return
}
// GC Start session gc process.
// it can do gc in times after gc lifetime.
func (manager *Manager) GC() {
- manager.provider.SessionGC(nil)
+ manager.provider.SessionGC()
time.AfterFunc(time.Duration(manager.config.Gclifetime)*time.Second, func() { manager.GC() })
}
@@ -306,7 +299,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
cookie, err := r.Cookie(manager.config.CookieName)
if err != nil || cookie.Value == "" {
//delete old cookie
- session, _ = manager.provider.SessionRead(nil, sid)
+ session, _ = manager.provider.SessionRead(sid)
cookie = &http.Cookie{Name: manager.config.CookieName,
Value: url.QueryEscape(sid),
Path: "/",
@@ -316,7 +309,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
}
} else {
oldsid, _ := url.QueryUnescape(cookie.Value)
- session, _ = manager.provider.SessionRegenerate(nil, oldsid, sid)
+ session, _ = manager.provider.SessionRegenerate(oldsid, sid)
cookie.Value = url.QueryEscape(sid)
cookie.HttpOnly = true
cookie.Path = "/"
@@ -340,7 +333,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
// GetActiveSession Get all active sessions count number.
func (manager *Manager) GetActiveSession() int {
- return manager.provider.SessionAll(nil)
+ return manager.provider.SessionAll()
}
// SetSecure Set cookie with https.
diff --git a/server/web/session/ssdb/sess_ssdb.go b/session/ssdb/sess_ssdb.go
similarity index 66%
rename from server/web/session/ssdb/sess_ssdb.go
rename to session/ssdb/sess_ssdb.go
index 0adc41bd..de0c6360 100644
--- a/server/web/session/ssdb/sess_ssdb.go
+++ b/session/ssdb/sess_ssdb.go
@@ -1,17 +1,14 @@
package ssdb
import (
- "context"
- "encoding/json"
"errors"
"net/http"
"strconv"
"strings"
"sync"
+ "github.com/astaxie/beego/session"
"github.com/ssdb/gossdb/ssdb"
-
- "github.com/astaxie/beego/server/web/session"
)
var ssdbProvider = &Provider{}
@@ -19,50 +16,35 @@ var ssdbProvider = &Provider{}
// Provider holds ssdb client and configs
type Provider struct {
client *ssdb.Client
- Host string `json:"host"`
- Port int `json:"port"`
+ host string
+ port int
maxLifetime int64
}
func (p *Provider) connectInit() error {
var err error
- if p.Host == "" || p.Port == 0 {
+ if p.host == "" || p.port == 0 {
return errors.New("SessionInit First")
}
- p.client, err = ssdb.Connect(p.Host, p.Port)
+ p.client, err = ssdb.Connect(p.host, p.port)
return err
}
// SessionInit init the ssdb with the config
-func (p *Provider) SessionInit(ctx context.Context, maxLifetime int64, cfg string) error {
+func (p *Provider) SessionInit(maxLifetime int64, savePath string) error {
p.maxLifetime = maxLifetime
+ address := strings.Split(savePath, ":")
+ p.host = address[0]
- cfg = strings.TrimSpace(cfg)
var err error
- // we think this is v2.0, using json to init the session
- if strings.HasPrefix(cfg, "{") {
- err = json.Unmarshal([]byte(cfg), p)
- } else {
- err = p.initOldStyle(cfg)
- }
- if err != nil {
+ if p.port, err = strconv.Atoi(address[1]); err != nil {
return err
}
return p.connectInit()
}
-// for v1.x
-func (p *Provider) initOldStyle(savePath string) error {
- address := strings.Split(savePath, ":")
- p.Host = address[0]
-
- var err error
- p.Port, err = strconv.Atoi(address[1])
- return err
-}
-
// SessionRead return a ssdb client session Store
-func (p *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
+func (p *Provider) SessionRead(sid string) (session.Store, error) {
if p.client == nil {
if err := p.connectInit(); err != nil {
return nil, err
@@ -86,10 +68,10 @@ func (p *Provider) SessionRead(ctx context.Context, sid string) (session.Store,
}
// SessionExist judged whether sid is exist in session
-func (p *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+func (p *Provider) SessionExist(sid string) bool {
if p.client == nil {
if err := p.connectInit(); err != nil {
- return false, err
+ panic(err)
}
}
value, err := p.client.Get(sid)
@@ -97,14 +79,14 @@ func (p *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
panic(err)
}
if value == nil || len(value.(string)) == 0 {
- return false, nil
+ return false
}
- return true, nil
+ return true
}
// SessionRegenerate regenerate session with new sid and delete oldsid
-func (p *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
- // conn.Do("setx", key, v, ttl)
+func (p *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
+ //conn.Do("setx", key, v, ttl)
if p.client == nil {
if err := p.connectInit(); err != nil {
return nil, err
@@ -136,7 +118,7 @@ func (p *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (s
}
// SessionDestroy destroy the sid
-func (p *Provider) SessionDestroy(ctx context.Context, sid string) error {
+func (p *Provider) SessionDestroy(sid string) error {
if p.client == nil {
if err := p.connectInit(); err != nil {
return err
@@ -147,11 +129,11 @@ func (p *Provider) SessionDestroy(ctx context.Context, sid string) error {
}
// SessionGC not implemented
-func (p *Provider) SessionGC(context.Context) {
+func (p *Provider) SessionGC() {
}
// SessionAll not implemented
-func (p *Provider) SessionAll(context.Context) int {
+func (p *Provider) SessionAll() int {
return 0
}
@@ -165,7 +147,7 @@ type SessionStore struct {
}
// Set the key and value
-func (s *SessionStore) Set(ctx context.Context, key, value interface{}) error {
+func (s *SessionStore) Set(key, value interface{}) error {
s.lock.Lock()
defer s.lock.Unlock()
s.values[key] = value
@@ -173,7 +155,7 @@ func (s *SessionStore) Set(ctx context.Context, key, value interface{}) error {
}
// Get return the value by the key
-func (s *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
+func (s *SessionStore) Get(key interface{}) interface{} {
s.lock.Lock()
defer s.lock.Unlock()
if value, ok := s.values[key]; ok {
@@ -183,7 +165,7 @@ func (s *SessionStore) Get(ctx context.Context, key interface{}) interface{} {
}
// Delete the key in session store
-func (s *SessionStore) Delete(ctx context.Context, key interface{}) error {
+func (s *SessionStore) Delete(key interface{}) error {
s.lock.Lock()
defer s.lock.Unlock()
delete(s.values, key)
@@ -191,7 +173,7 @@ func (s *SessionStore) Delete(ctx context.Context, key interface{}) error {
}
// Flush delete all keys and values
-func (s *SessionStore) Flush(context.Context) error {
+func (s *SessionStore) Flush() error {
s.lock.Lock()
defer s.lock.Unlock()
s.values = make(map[interface{}]interface{})
@@ -199,12 +181,12 @@ func (s *SessionStore) Flush(context.Context) error {
}
// SessionID return the sessionID
-func (s *SessionStore) SessionID(context.Context) string {
+func (s *SessionStore) SessionID() string {
return s.sid
}
// SessionRelease Store the keyvalues into ssdb
-func (s *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
+func (s *SessionStore) SessionRelease(w http.ResponseWriter) {
b, err := session.EncodeGob(s.values)
if err != nil {
return
diff --git a/server/web/staticfile.go b/staticfile.go
similarity index 96%
rename from server/web/staticfile.go
rename to staticfile.go
index aa3f35d8..84e9aa7b 100644
--- a/server/web/staticfile.go
+++ b/staticfile.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"bytes"
@@ -26,10 +26,9 @@ import (
"sync"
"time"
- "github.com/astaxie/beego/core/logs"
- lru "github.com/hashicorp/golang-lru"
-
- "github.com/astaxie/beego/server/web/context"
+ "github.com/astaxie/beego/context"
+ "github.com/astaxie/beego/logs"
+ "github.com/hashicorp/golang-lru"
)
var errNotStaticRequest = errors.New("request not a static file request")
@@ -203,7 +202,7 @@ func searchFile(ctx *context.Context) (string, os.FileInfo, error) {
if !strings.Contains(requestPath, prefix) {
continue
}
- if prefix != "/" && len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' {
+ if prefix != "/" && len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' {
continue
}
filePath := path.Join(staticDir, requestPath[len(prefix):])
diff --git a/server/web/staticfile_test.go b/staticfile_test.go
similarity index 99%
rename from server/web/staticfile_test.go
rename to staticfile_test.go
index 0725a2f8..e46c13ec 100644
--- a/server/web/staticfile_test.go
+++ b/staticfile_test.go
@@ -1,4 +1,4 @@
-package web
+package beego
import (
"bytes"
diff --git a/server/web/swagger/swagger.go b/swagger/swagger.go
similarity index 100%
rename from server/web/swagger/swagger.go
rename to swagger/swagger.go
diff --git a/task/govenor_command.go b/task/govenor_command.go
deleted file mode 100644
index 15e25e43..00000000
--- a/task/govenor_command.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package task
-
-import (
- "context"
- "fmt"
- "html/template"
-
- "github.com/pkg/errors"
-
- "github.com/astaxie/beego/core/governor"
-)
-
-type listTaskCommand struct {
-}
-
-func (l *listTaskCommand) Execute(params ...interface{}) *governor.Result {
- resultList := make([][]string, 0, len(globalTaskManager.adminTaskList))
- for tname, tk := range globalTaskManager.adminTaskList {
- result := []string{
- template.HTMLEscapeString(tname),
- template.HTMLEscapeString(tk.GetSpec(nil)),
- template.HTMLEscapeString(tk.GetStatus(nil)),
- template.HTMLEscapeString(tk.GetPrev(context.Background()).String()),
- }
- resultList = append(resultList, result)
- }
-
- return &governor.Result{
- Status: 200,
- Content: resultList,
- }
-}
-
-type runTaskCommand struct {
-}
-
-func (r *runTaskCommand) Execute(params ...interface{}) *governor.Result {
- if len(params) == 0 {
- return &governor.Result{
- Status: 400,
- Error: errors.New("task name not passed"),
- }
- }
-
- tn, ok := params[0].(string)
-
- if !ok {
- return &governor.Result{
- Status: 400,
- Error: errors.New("parameter is invalid"),
- }
- }
-
- if t, ok := globalTaskManager.adminTaskList[tn]; ok {
- err := t.Run(context.Background())
- if err != nil {
- return &governor.Result{
- Status: 500,
- Error: err,
- }
- }
- return &governor.Result{
- Status: 200,
- Content: t.GetStatus(context.Background()),
- }
- } else {
- return &governor.Result{
- Status: 400,
- Error: errors.New(fmt.Sprintf("task with name %s not found", tn)),
- }
- }
-
-}
-
-func registerCommands() {
- governor.RegisterCommand("task", "list", &listTaskCommand{})
- governor.RegisterCommand("task", "run", &runTaskCommand{})
-}
diff --git a/task/governor_command_test.go b/task/governor_command_test.go
deleted file mode 100644
index 00ed37f2..00000000
--- a/task/governor_command_test.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2020
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package task
-
-import (
- "context"
- "errors"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-type countTask struct {
- cnt int
- mockErr error
-}
-
-func (c *countTask) GetSpec(ctx context.Context) string {
- return "AAA"
-}
-
-func (c *countTask) GetStatus(ctx context.Context) string {
- return "SUCCESS"
-}
-
-func (c *countTask) Run(ctx context.Context) error {
- c.cnt++
- return c.mockErr
-}
-
-func (c *countTask) SetNext(ctx context.Context, time time.Time) {
-}
-
-func (c *countTask) GetNext(ctx context.Context) time.Time {
- return time.Now()
-}
-
-func (c *countTask) SetPrev(ctx context.Context, time time.Time) {
-}
-
-func (c *countTask) GetPrev(ctx context.Context) time.Time {
- return time.Now()
-}
-
-func TestRunTaskCommand_Execute(t *testing.T) {
- task := &countTask{}
- AddTask("count", task)
-
- cmd := &runTaskCommand{}
-
- res := cmd.Execute()
- assert.NotNil(t, res)
- assert.NotNil(t, res.Error)
- assert.Equal(t, "task name not passed", res.Error.Error())
-
- res = cmd.Execute(10)
- assert.NotNil(t, res)
- assert.NotNil(t, res.Error)
- assert.Equal(t, "parameter is invalid", res.Error.Error())
-
- res = cmd.Execute("CCCC")
- assert.NotNil(t, res)
- assert.NotNil(t, res.Error)
- assert.Equal(t, "task with name CCCC not found", res.Error.Error())
-
- res = cmd.Execute("count")
- assert.NotNil(t, res)
- assert.True(t, res.IsSuccess())
-
- task.mockErr = errors.New("mock error")
- res = cmd.Execute("count")
- assert.NotNil(t, res)
- assert.NotNil(t, res.Error)
- assert.Equal(t, "mock error", res.Error.Error())
-}
-
-func TestListTaskCommand_Execute(t *testing.T) {
- task := &countTask{}
-
- cmd := &listTaskCommand{}
-
- res := cmd.Execute()
-
- assert.True(t, res.IsSuccess())
-
- _, ok := res.Content.([][]string)
- assert.True(t, ok)
-
- AddTask("count", task)
-
- res = cmd.Execute()
-
- assert.True(t, res.IsSuccess())
-
- rl, ok := res.Content.([][]string)
- assert.True(t, ok)
- assert.Equal(t, 1, len(rl))
-}
diff --git a/task/task_test.go b/task/task_test.go
deleted file mode 100644
index 2cb807ce..00000000
--- a/task/task_test.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package task
-
-import (
- "context"
- "errors"
- "fmt"
- "sync"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestParse(t *testing.T) {
- m := newTaskManager()
- defer m.ClearTask()
- tk := NewTask("taska", "0/30 * * * * *", func(ctx context.Context) error {
- fmt.Println("hello world")
- return nil
- })
- err := tk.Run(nil)
- if err != nil {
- t.Fatal(err)
- }
- m.AddTask("taska", tk)
- m.StartTask()
- time.Sleep(3 * time.Second)
- m.StopTask()
-}
-
-func TestModifyTaskListAfterRunning(t *testing.T) {
- m := newTaskManager()
- defer m.ClearTask()
- tk := NewTask("taskb", "0/30 * * * * *", func(ctx context.Context) error {
- fmt.Println("hello world")
- return nil
- })
- err := tk.Run(nil)
- if err != nil {
- t.Fatal(err)
- }
- m.AddTask("taskb", tk)
- m.StartTask()
- go func() {
- m.DeleteTask("taskb")
- }()
- go func() {
- m.AddTask("taskb1", tk)
- }()
-
- time.Sleep(3 * time.Second)
- m.StopTask()
-}
-
-func TestSpec(t *testing.T) {
- m := newTaskManager()
- defer m.ClearTask()
- wg := &sync.WaitGroup{}
- wg.Add(2)
- tk1 := NewTask("tk1", "0 12 * * * *", func(ctx context.Context) error { fmt.Println("tk1"); return nil })
- tk2 := NewTask("tk2", "0,10,20 * * * * *", func(ctx context.Context) error { fmt.Println("tk2"); wg.Done(); return nil })
- tk3 := NewTask("tk3", "0 10 * * * *", func(ctx context.Context) error { fmt.Println("tk3"); wg.Done(); return nil })
-
- m.AddTask("tk1", tk1)
- m.AddTask("tk2", tk2)
- m.AddTask("tk3", tk3)
- m.StartTask()
- defer m.StopTask()
-
- select {
- case <-time.After(200 * time.Second):
- t.FailNow()
- case <-wait(wg):
- }
-}
-
-func TestTask_Run(t *testing.T) {
- cnt := -1
- task := func(ctx context.Context) error {
- cnt++
- fmt.Printf("Hello, world! %d \n", cnt)
- return errors.New(fmt.Sprintf("Hello, world! %d", cnt))
- }
- tk := NewTask("taska", "0/30 * * * * *", task)
- for i := 0; i < 200; i++ {
- e := tk.Run(nil)
- assert.NotNil(t, e)
- }
-
- l := tk.Errlist
- assert.Equal(t, 100, len(l))
- assert.Equal(t, "Hello, world! 100", l[0].errinfo)
- assert.Equal(t, "Hello, world! 101", l[1].errinfo)
-}
-
-func wait(wg *sync.WaitGroup) chan bool {
- ch := make(chan bool)
- go func() {
- wg.Wait()
- ch <- true
- }()
- return ch
-}
diff --git a/server/web/template.go b/template.go
similarity index 97%
rename from server/web/template.go
rename to template.go
index d582dcda..59875be7 100644
--- a/server/web/template.go
+++ b/template.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"errors"
@@ -27,8 +27,8 @@ import (
"strings"
"sync"
- "github.com/astaxie/beego/core/logs"
- "github.com/astaxie/beego/core/utils"
+ "github.com/astaxie/beego/logs"
+ "github.com/astaxie/beego/utils"
)
var (
@@ -368,14 +368,14 @@ func SetTemplateFSFunc(fnt templateFSFunc) {
}
// SetViewsPath sets view directory path in beego application.
-func SetViewsPath(path string) *HttpServer {
+func SetViewsPath(path string) *App {
BConfig.WebConfig.ViewsPath = path
return BeeApp
}
// SetStaticPath sets static directory path and proper url pattern in beego application.
// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public".
-func SetStaticPath(url string, path string) *HttpServer {
+func SetStaticPath(url string, path string) *App {
if !strings.HasPrefix(url, "/") {
url = "/" + url
}
@@ -387,7 +387,7 @@ func SetStaticPath(url string, path string) *HttpServer {
}
// DelStaticPath removes the static folder setting in this url pattern in beego application.
-func DelStaticPath(url string) *HttpServer {
+func DelStaticPath(url string) *App {
if !strings.HasPrefix(url, "/") {
url = "/" + url
}
@@ -399,7 +399,7 @@ func DelStaticPath(url string) *HttpServer {
}
// AddTemplateEngine add a new templatePreProcessor which support extension
-func AddTemplateEngine(extension string, fn templatePreProcessor) *HttpServer {
+func AddTemplateEngine(extension string, fn templatePreProcessor) *App {
AddTemplateExt(extension)
beeTemplateEngines[extension] = fn
return BeeApp
diff --git a/server/web/template_test.go b/template_test.go
similarity index 88%
rename from server/web/template_test.go
rename to template_test.go
index b542494d..287faadc 100644
--- a/server/web/template_test.go
+++ b/template_test.go
@@ -12,19 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"bytes"
+ "github.com/astaxie/beego/testdata"
+ "github.com/elazarl/go-bindata-assetfs"
"net/http"
"os"
"path/filepath"
"testing"
-
- assetfs "github.com/elazarl/go-bindata-assetfs"
- "github.com/stretchr/testify/assert"
-
- "github.com/astaxie/beego/test"
)
var header = `{{define "header"}}
@@ -49,9 +46,7 @@ var block = `{{define "block"}}
{{end}}`
func TestTemplate(t *testing.T) {
- wkdir, err := os.Getwd()
- assert.Nil(t, err)
- dir := filepath.Join(wkdir, "_beeTmp", "TestTemplate")
+ dir := "_beeTmp"
files := []string{
"header.tpl",
"index.tpl",
@@ -61,8 +56,7 @@ func TestTemplate(t *testing.T) {
t.Fatal(err)
}
for k, name := range files {
- dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
- assert.Nil(t, dirErr)
+ os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
if f, err := os.Create(filepath.Join(dir, name)); err != nil {
t.Fatal(err)
} else {
@@ -113,9 +107,7 @@ var user = `
`
func TestRelativeTemplate(t *testing.T) {
- wkdir, err := os.Getwd()
- assert.Nil(t, err)
- dir := filepath.Join(wkdir, "_beeTmp")
+ dir := "_beeTmp"
//Just add dir to known viewPaths
if err := AddViewPath(dir); err != nil {
@@ -226,10 +218,7 @@ var output = `
`
func TestTemplateLayout(t *testing.T) {
- wkdir, err := os.Getwd()
- assert.Nil(t, err)
-
- dir := filepath.Join(wkdir, "_beeTmp", "TestTemplateLayout")
+ dir := "_beeTmp"
files := []string{
"add.tpl",
"layout_blog.tpl",
@@ -237,22 +226,17 @@ func TestTemplateLayout(t *testing.T) {
if err := os.MkdirAll(dir, 0777); err != nil {
t.Fatal(err)
}
-
for k, name := range files {
- dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
- assert.Nil(t, dirErr)
+ os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
if f, err := os.Create(filepath.Join(dir, name)); err != nil {
t.Fatal(err)
} else {
if k == 0 {
- _, writeErr := f.WriteString(add)
- assert.Nil(t, writeErr)
+ f.WriteString(add)
} else if k == 1 {
- _, writeErr := f.WriteString(layoutBlog)
- assert.Nil(t, writeErr)
+ f.WriteString(layoutBlog)
}
- clErr := f.Close()
- assert.Nil(t, clErr)
+ f.Close()
}
}
if err := AddViewPath(dir); err != nil {
@@ -263,7 +247,6 @@ func TestTemplateLayout(t *testing.T) {
t.Fatalf("should be 2 but got %v", len(beeTemplates))
}
out := bytes.NewBufferString("")
-
if err := beeTemplates["add.tpl"].ExecuteTemplate(out, "add.tpl", map[string]string{"Title": "Hello", "SomeVar": "val"}); err != nil {
t.Fatal(err)
}
@@ -308,7 +291,7 @@ var outputBinData = `
func TestFsBinData(t *testing.T) {
SetTemplateFSFunc(func() http.FileSystem {
- return TestingFileSystem{&assetfs.AssetFS{Asset: test.Asset, AssetDir: test.AssetDir, AssetInfo: test.AssetInfo}}
+ return TestingFileSystem{&assetfs.AssetFS{Asset: testdata.Asset, AssetDir: testdata.AssetDir, AssetInfo: testdata.AssetInfo}}
})
dir := "views"
if err := AddViewPath("views"); err != nil {
diff --git a/server/web/templatefunc.go b/templatefunc.go
similarity index 98%
rename from server/web/templatefunc.go
rename to templatefunc.go
index 53c99018..ba1ec5eb 100644
--- a/server/web/templatefunc.go
+++ b/templatefunc.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package web
+package beego
import (
"errors"
@@ -58,11 +58,11 @@ func HTML2str(html string) string {
re := regexp.MustCompile(`\<[\S\s]+?\>`)
html = re.ReplaceAllStringFunc(html, strings.ToLower)
- // remove STYLE
+ //remove STYLE
re = regexp.MustCompile(`\