mirror of
https://github.com/astaxie/beego.git
synced 2024-12-25 18:00:48 +00:00
Merge branch 'develop-2.0' of github.com:astaxie/beego into change_redis_provider
This commit is contained in:
commit
0813471202
@ -48,22 +48,39 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Configer defines how to get and set value from configuration raw data.
|
// Configer defines how to get and set value from configuration raw data.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type Configer interface {
|
type Configer interface {
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
Set(key, val string) error //support section::key type in given key when using ini type.
|
Set(key, val string) error //support section::key type in given key when using ini type.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
Strings(key string) []string //get string slice
|
Strings(key string) []string //get string slice
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
Int(key string) (int, error)
|
Int(key string) (int, error)
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
Int64(key string) (int64, error)
|
Int64(key string) (int64, error)
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
Bool(key string) (bool, error)
|
Bool(key string) (bool, error)
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
Float(key string) (float64, error)
|
Float(key string) (float64, error)
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
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.
|
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.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
DefaultStrings(key string, defaultVal []string) []string //get string slice
|
DefaultStrings(key string, defaultVal []string) []string //get string slice
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
DefaultInt(key string, defaultVal int) int
|
DefaultInt(key string, defaultVal int) int
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
DefaultInt64(key string, defaultVal int64) int64
|
DefaultInt64(key string, defaultVal int64) int64
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
DefaultBool(key string, defaultVal bool) bool
|
DefaultBool(key string, defaultVal bool) bool
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
DefaultFloat(key string, defaultVal float64) float64
|
DefaultFloat(key string, defaultVal float64) float64
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
DIY(key string) (interface{}, error)
|
DIY(key string) (interface{}, error)
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
GetSection(section string) (map[string]string, error)
|
GetSection(section string) (map[string]string, error)
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
SaveConfigFile(filename string) error
|
SaveConfigFile(filename string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
config/env/env.go
vendored
5
config/env/env.go
vendored
@ -36,6 +36,7 @@ func init() {
|
|||||||
|
|
||||||
// Get returns a value by key.
|
// Get returns a value by key.
|
||||||
// If the key does not exist, the default value will be returned.
|
// If the key does not exist, the default value will be returned.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func Get(key string, defVal string) string {
|
func Get(key string, defVal string) string {
|
||||||
if val := env.Get(key); val != nil {
|
if val := env.Get(key); val != nil {
|
||||||
return val.(string)
|
return val.(string)
|
||||||
@ -45,6 +46,7 @@ func Get(key string, defVal string) string {
|
|||||||
|
|
||||||
// MustGet returns a value by key.
|
// MustGet returns a value by key.
|
||||||
// If the key does not exist, it will return an error.
|
// If the key does not exist, it will return an error.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func MustGet(key string) (string, error) {
|
func MustGet(key string) (string, error) {
|
||||||
if val := env.Get(key); val != nil {
|
if val := env.Get(key); val != nil {
|
||||||
return val.(string), nil
|
return val.(string), nil
|
||||||
@ -54,12 +56,14 @@ func MustGet(key string) (string, error) {
|
|||||||
|
|
||||||
// Set sets a value in the ENV copy.
|
// Set sets a value in the ENV copy.
|
||||||
// This does not affect the child process environment.
|
// This does not affect the child process environment.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func Set(key string, value string) {
|
func Set(key string, value string) {
|
||||||
env.Set(key, value)
|
env.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustSet sets a value in the ENV copy and the child process environment.
|
// MustSet sets a value in the ENV copy and the child process environment.
|
||||||
// It returns an error in case the set operation failed.
|
// It returns an error in case the set operation failed.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func MustSet(key string, value string) error {
|
func MustSet(key string, value string) error {
|
||||||
err := os.Setenv(key, value)
|
err := os.Setenv(key, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,6 +74,7 @@ func MustSet(key string, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAll returns all keys/values in the current child process environment.
|
// GetAll returns all keys/values in the current child process environment.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func GetAll() map[string]string {
|
func GetAll() map[string]string {
|
||||||
items := env.Items()
|
items := env.Items()
|
||||||
envs := make(map[string]string, env.Count())
|
envs := make(map[string]string, env.Count())
|
||||||
|
@ -27,16 +27,16 @@ type fakeConfigContainer struct {
|
|||||||
func (c *fakeConfigContainer) getData(key string) string {
|
func (c *fakeConfigContainer) getData(key string) string {
|
||||||
return c.data[strings.ToLower(key)]
|
return c.data[strings.ToLower(key)]
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) Set(key, val string) error {
|
func (c *fakeConfigContainer) Set(key, val string) error {
|
||||||
c.data[strings.ToLower(key)] = val
|
c.data[strings.ToLower(key)] = val
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) String(key string) string {
|
func (c *fakeConfigContainer) String(key string) string {
|
||||||
return c.getData(key)
|
return c.getData(key)
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DefaultString(key string, defaultval string) string {
|
func (c *fakeConfigContainer) DefaultString(key string, defaultval string) string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -44,7 +44,7 @@ func (c *fakeConfigContainer) DefaultString(key string, defaultval string) strin
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) Strings(key string) []string {
|
func (c *fakeConfigContainer) Strings(key string) []string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -52,7 +52,7 @@ func (c *fakeConfigContainer) Strings(key string) []string {
|
|||||||
}
|
}
|
||||||
return strings.Split(v, ";")
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@ -60,11 +60,11 @@ func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) Int(key string) (int, error) {
|
func (c *fakeConfigContainer) Int(key string) (int, error) {
|
||||||
return strconv.Atoi(c.getData(key))
|
return strconv.Atoi(c.getData(key))
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int {
|
func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int {
|
||||||
v, err := c.Int(key)
|
v, err := c.Int(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -72,11 +72,11 @@ func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int {
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) Int64(key string) (int64, error) {
|
func (c *fakeConfigContainer) Int64(key string) (int64, error) {
|
||||||
return strconv.ParseInt(c.getData(key), 10, 64)
|
return strconv.ParseInt(c.getData(key), 10, 64)
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
||||||
v, err := c.Int64(key)
|
v, err := c.Int64(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -84,11 +84,11 @@ func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) Bool(key string) (bool, error) {
|
func (c *fakeConfigContainer) Bool(key string) (bool, error) {
|
||||||
return ParseBool(c.getData(key))
|
return ParseBool(c.getData(key))
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
||||||
v, err := c.Bool(key)
|
v, err := c.Bool(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -96,11 +96,11 @@ func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) Float(key string) (float64, error) {
|
func (c *fakeConfigContainer) Float(key string) (float64, error) {
|
||||||
return strconv.ParseFloat(c.getData(key), 64)
|
return strconv.ParseFloat(c.getData(key), 64)
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
||||||
v, err := c.Float(key)
|
v, err := c.Float(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,18 +108,18 @@ func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) DIY(key string) (interface{}, error) {
|
func (c *fakeConfigContainer) DIY(key string) (interface{}, error) {
|
||||||
if v, ok := c.data[strings.ToLower(key)]; ok {
|
if v, ok := c.data[strings.ToLower(key)]; ok {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("key not find")
|
return nil, errors.New("key not find")
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) GetSection(section string) (map[string]string, error) {
|
func (c *fakeConfigContainer) GetSection(section string) (map[string]string, error) {
|
||||||
return nil, errors.New("not implement in the fakeConfigContainer")
|
return nil, errors.New("not implement in the fakeConfigContainer")
|
||||||
}
|
}
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *fakeConfigContainer) SaveConfigFile(filename string) error {
|
func (c *fakeConfigContainer) SaveConfigFile(filename string) error {
|
||||||
return errors.New("not implement in the fakeConfigContainer")
|
return errors.New("not implement in the fakeConfigContainer")
|
||||||
}
|
}
|
||||||
@ -127,6 +127,7 @@ func (c *fakeConfigContainer) SaveConfigFile(filename string) error {
|
|||||||
var _ Configer = new(fakeConfigContainer)
|
var _ Configer = new(fakeConfigContainer)
|
||||||
|
|
||||||
// NewFakeConfig return a fake Configer
|
// NewFakeConfig return a fake Configer
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func NewFakeConfig() Configer {
|
func NewFakeConfig() Configer {
|
||||||
return &fakeConfigContainer{
|
return &fakeConfigContainer{
|
||||||
data: make(map[string]string),
|
data: make(map[string]string),
|
||||||
|
@ -41,10 +41,12 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// IniConfig implements Config to parse ini file.
|
// IniConfig implements Config to parse ini file.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type IniConfig struct {
|
type IniConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse creates a new Config and parses the file configuration from the named file.
|
// Parse creates a new Config and parses the file configuration from the named file.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (ini *IniConfig) Parse(name string) (Configer, error) {
|
func (ini *IniConfig) Parse(name string) (Configer, error) {
|
||||||
return ini.parseFile(name)
|
return ini.parseFile(name)
|
||||||
}
|
}
|
||||||
@ -208,6 +210,7 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
|
|||||||
// ParseData parse ini the data
|
// ParseData parse ini the data
|
||||||
// When include other.conf,other.conf is either absolute directory
|
// When include other.conf,other.conf is either absolute directory
|
||||||
// or under beego in default temporary directory(/tmp/beego[-username]).
|
// or under beego in default temporary directory(/tmp/beego[-username]).
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
|
func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
|
||||||
dir := "beego"
|
dir := "beego"
|
||||||
currentUser, err := user.Current()
|
currentUser, err := user.Current()
|
||||||
@ -224,6 +227,7 @@ func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
|
|||||||
|
|
||||||
// IniConfigContainer A Config represents the ini configuration.
|
// IniConfigContainer A Config represents the ini configuration.
|
||||||
// When set and get value, support key as section:name type.
|
// When set and get value, support key as section:name type.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type IniConfigContainer struct {
|
type IniConfigContainer struct {
|
||||||
data map[string]map[string]string // section=> key:val
|
data map[string]map[string]string // section=> key:val
|
||||||
sectionComment map[string]string // section : comment
|
sectionComment map[string]string // section : comment
|
||||||
@ -232,12 +236,14 @@ type IniConfigContainer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
// Bool returns the boolean value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) Bool(key string) (bool, error) {
|
func (c *IniConfigContainer) Bool(key string) (bool, error) {
|
||||||
return ParseBool(c.getdata(key))
|
return ParseBool(c.getdata(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBool returns the boolean value for a given key.
|
// DefaultBool returns the boolean value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
||||||
v, err := c.Bool(key)
|
v, err := c.Bool(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -247,12 +253,14 @@ func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the integer value for a given key.
|
// Int returns the integer value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) Int(key string) (int, error) {
|
func (c *IniConfigContainer) Int(key string) (int, error) {
|
||||||
return strconv.Atoi(c.getdata(key))
|
return strconv.Atoi(c.getdata(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultInt returns the integer value for a given key.
|
// DefaultInt returns the integer value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
|
func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
|
||||||
v, err := c.Int(key)
|
v, err := c.Int(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -262,12 +270,14 @@ func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int64 returns the int64 value for a given key.
|
// Int64 returns the int64 value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) Int64(key string) (int64, error) {
|
func (c *IniConfigContainer) Int64(key string) (int64, error) {
|
||||||
return strconv.ParseInt(c.getdata(key), 10, 64)
|
return strconv.ParseInt(c.getdata(key), 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultInt64 returns the int64 value for a given key.
|
// DefaultInt64 returns the int64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
||||||
v, err := c.Int64(key)
|
v, err := c.Int64(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -277,12 +287,14 @@ func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Float returns the float value for a given key.
|
// Float returns the float value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) Float(key string) (float64, error) {
|
func (c *IniConfigContainer) Float(key string) (float64, error) {
|
||||||
return strconv.ParseFloat(c.getdata(key), 64)
|
return strconv.ParseFloat(c.getdata(key), 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultFloat returns the float64 value for a given key.
|
// DefaultFloat returns the float64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
||||||
v, err := c.Float(key)
|
v, err := c.Float(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -292,12 +304,14 @@ func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float6
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string value for a given key.
|
// String returns the string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) String(key string) string {
|
func (c *IniConfigContainer) String(key string) string {
|
||||||
return c.getdata(key)
|
return c.getdata(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultString returns the string value for a given key.
|
// DefaultString returns the string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DefaultString(key string, defaultval string) string {
|
func (c *IniConfigContainer) DefaultString(key string, defaultval string) string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -308,6 +322,7 @@ func (c *IniConfigContainer) DefaultString(key string, defaultval string) string
|
|||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
// Return nil if config value does not exist or is empty.
|
// Return nil if config value does not exist or is empty.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) Strings(key string) []string {
|
func (c *IniConfigContainer) Strings(key string) []string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -318,6 +333,7 @@ func (c *IniConfigContainer) Strings(key string) []string {
|
|||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@ -327,6 +343,7 @@ func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSection returns map for the given section
|
// GetSection returns map for the given section
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) GetSection(section string) (map[string]string, error) {
|
func (c *IniConfigContainer) GetSection(section string) (map[string]string, error) {
|
||||||
if v, ok := c.data[section]; ok {
|
if v, ok := c.data[section]; ok {
|
||||||
return v, nil
|
return v, nil
|
||||||
@ -337,6 +354,7 @@ func (c *IniConfigContainer) GetSection(section string) (map[string]string, erro
|
|||||||
// SaveConfigFile save the config into file.
|
// SaveConfigFile save the config into file.
|
||||||
//
|
//
|
||||||
// BUG(env): The environment variable config item will be saved with real value in SaveConfigFile Function.
|
// BUG(env): The environment variable config item will be saved with real value in SaveConfigFile Function.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
|
func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
|
||||||
// Write configuration file by filename.
|
// Write configuration file by filename.
|
||||||
f, err := os.Create(filename)
|
f, err := os.Create(filename)
|
||||||
@ -437,6 +455,7 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
// Set writes a new value for key.
|
// Set writes a new value for key.
|
||||||
// if write to one section, the key need be "section::key".
|
// if write to one section, the key need be "section::key".
|
||||||
// if the section is not existed, it panics.
|
// if the section is not existed, it panics.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) Set(key, value string) error {
|
func (c *IniConfigContainer) Set(key, value string) error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
@ -465,6 +484,7 @@ func (c *IniConfigContainer) Set(key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DIY returns the raw value by a given key.
|
// DIY returns the raw value by a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) {
|
func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) {
|
||||||
if v, ok := c.data[strings.ToLower(key)]; ok {
|
if v, ok := c.data[strings.ToLower(key)]; ok {
|
||||||
return v, nil
|
return v, nil
|
||||||
|
@ -26,10 +26,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// JSONConfig is a json config parser and implements Config interface.
|
// JSONConfig is a json config parser and implements Config interface.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type JSONConfig struct {
|
type JSONConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse returns a ConfigContainer with parsed json config map.
|
// Parse returns a ConfigContainer with parsed json config map.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (js *JSONConfig) Parse(filename string) (Configer, error) {
|
func (js *JSONConfig) Parse(filename string) (Configer, error) {
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -45,6 +47,7 @@ func (js *JSONConfig) Parse(filename string) (Configer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseData returns a ConfigContainer with json string
|
// ParseData returns a ConfigContainer with json string
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
|
func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
|
||||||
x := &JSONConfigContainer{
|
x := &JSONConfigContainer{
|
||||||
data: make(map[string]interface{}),
|
data: make(map[string]interface{}),
|
||||||
@ -66,12 +69,14 @@ func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
|
|||||||
|
|
||||||
// JSONConfigContainer A Config represents the json configuration.
|
// JSONConfigContainer A Config represents the json configuration.
|
||||||
// Only when get value, support key as section:name type.
|
// Only when get value, support key as section:name type.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type JSONConfigContainer struct {
|
type JSONConfigContainer struct {
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
// Bool returns the boolean value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) Bool(key string) (bool, error) {
|
func (c *JSONConfigContainer) Bool(key string) (bool, error) {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
@ -82,6 +87,7 @@ func (c *JSONConfigContainer) Bool(key string) (bool, error) {
|
|||||||
|
|
||||||
// DefaultBool return the bool value if has no error
|
// DefaultBool return the bool value if has no error
|
||||||
// otherwise return the defaultval
|
// otherwise return the defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
func (c *JSONConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
||||||
if v, err := c.Bool(key); err == nil {
|
if v, err := c.Bool(key); err == nil {
|
||||||
return v
|
return v
|
||||||
@ -90,6 +96,7 @@ func (c *JSONConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the integer value for a given key.
|
// Int returns the integer value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) Int(key string) (int, error) {
|
func (c *JSONConfigContainer) Int(key string) (int, error) {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
@ -105,6 +112,7 @@ func (c *JSONConfigContainer) Int(key string) (int, error) {
|
|||||||
|
|
||||||
// DefaultInt returns the integer value for a given key.
|
// DefaultInt returns the integer value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DefaultInt(key string, defaultval int) int {
|
func (c *JSONConfigContainer) DefaultInt(key string, defaultval int) int {
|
||||||
if v, err := c.Int(key); err == nil {
|
if v, err := c.Int(key); err == nil {
|
||||||
return v
|
return v
|
||||||
@ -113,6 +121,7 @@ func (c *JSONConfigContainer) DefaultInt(key string, defaultval int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int64 returns the int64 value for a given key.
|
// Int64 returns the int64 value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) Int64(key string) (int64, error) {
|
func (c *JSONConfigContainer) Int64(key string) (int64, error) {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
@ -126,6 +135,7 @@ func (c *JSONConfigContainer) Int64(key string) (int64, error) {
|
|||||||
|
|
||||||
// DefaultInt64 returns the int64 value for a given key.
|
// DefaultInt64 returns the int64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
func (c *JSONConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
||||||
if v, err := c.Int64(key); err == nil {
|
if v, err := c.Int64(key); err == nil {
|
||||||
return v
|
return v
|
||||||
@ -134,6 +144,7 @@ func (c *JSONConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Float returns the float value for a given key.
|
// Float returns the float value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) Float(key string) (float64, error) {
|
func (c *JSONConfigContainer) Float(key string) (float64, error) {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
@ -147,6 +158,7 @@ func (c *JSONConfigContainer) Float(key string) (float64, error) {
|
|||||||
|
|
||||||
// DefaultFloat returns the float64 value for a given key.
|
// DefaultFloat returns the float64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
func (c *JSONConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
||||||
if v, err := c.Float(key); err == nil {
|
if v, err := c.Float(key); err == nil {
|
||||||
return v
|
return v
|
||||||
@ -155,6 +167,7 @@ func (c *JSONConfigContainer) DefaultFloat(key string, defaultval float64) float
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string value for a given key.
|
// String returns the string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) String(key string) string {
|
func (c *JSONConfigContainer) String(key string) string {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
@ -167,6 +180,7 @@ func (c *JSONConfigContainer) String(key string) string {
|
|||||||
|
|
||||||
// DefaultString returns the string value for a given key.
|
// DefaultString returns the string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DefaultString(key string, defaultval string) string {
|
func (c *JSONConfigContainer) DefaultString(key string, defaultval string) string {
|
||||||
// TODO FIXME should not use "" to replace non existence
|
// TODO FIXME should not use "" to replace non existence
|
||||||
if v := c.String(key); v != "" {
|
if v := c.String(key); v != "" {
|
||||||
@ -176,6 +190,7 @@ func (c *JSONConfigContainer) DefaultString(key string, defaultval string) strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) Strings(key string) []string {
|
func (c *JSONConfigContainer) Strings(key string) []string {
|
||||||
stringVal := c.String(key)
|
stringVal := c.String(key)
|
||||||
if stringVal == "" {
|
if stringVal == "" {
|
||||||
@ -186,6 +201,7 @@ func (c *JSONConfigContainer) Strings(key string) []string {
|
|||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
if v := c.Strings(key); v != nil {
|
if v := c.Strings(key); v != nil {
|
||||||
return v
|
return v
|
||||||
@ -194,6 +210,7 @@ func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSection returns map for the given section
|
// GetSection returns map for the given section
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) GetSection(section string) (map[string]string, error) {
|
func (c *JSONConfigContainer) GetSection(section string) (map[string]string, error) {
|
||||||
if v, ok := c.data[section]; ok {
|
if v, ok := c.data[section]; ok {
|
||||||
return v.(map[string]string), nil
|
return v.(map[string]string), nil
|
||||||
@ -202,6 +219,7 @@ func (c *JSONConfigContainer) GetSection(section string) (map[string]string, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveConfigFile save the config into file
|
// SaveConfigFile save the config into file
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) SaveConfigFile(filename string) (err error) {
|
func (c *JSONConfigContainer) SaveConfigFile(filename string) (err error) {
|
||||||
// Write configuration file by filename.
|
// Write configuration file by filename.
|
||||||
f, err := os.Create(filename)
|
f, err := os.Create(filename)
|
||||||
@ -218,6 +236,7 @@ func (c *JSONConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set writes a new value for key.
|
// Set writes a new value for key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) Set(key, val string) error {
|
func (c *JSONConfigContainer) Set(key, val string) error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
@ -226,6 +245,7 @@ func (c *JSONConfigContainer) Set(key, val string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DIY returns the raw value by a given key.
|
// DIY returns the raw value by a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) DIY(key string) (v interface{}, err error) {
|
func (c *JSONConfigContainer) DIY(key string) (v interface{}, err error) {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
@ -235,6 +255,7 @@ func (c *JSONConfigContainer) DIY(key string) (v interface{}, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// section.key or key
|
// section.key or key
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *JSONConfigContainer) getData(key string) interface{} {
|
func (c *JSONConfigContainer) getData(key string) interface{} {
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -46,9 +46,11 @@ import (
|
|||||||
// Config is a xml config parser and implements Config interface.
|
// Config is a xml config parser and implements Config interface.
|
||||||
// xml configurations should be included in <config></config> tag.
|
// xml configurations should be included in <config></config> tag.
|
||||||
// only support key/value pair as <key>value</key> as each item.
|
// only support key/value pair as <key>value</key> as each item.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type Config struct{}
|
type Config struct{}
|
||||||
|
|
||||||
// Parse returns a ConfigContainer with parsed xml config map.
|
// Parse returns a ConfigContainer with parsed xml config map.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (xc *Config) Parse(filename string) (config.Configer, error) {
|
func (xc *Config) Parse(filename string) (config.Configer, error) {
|
||||||
context, err := ioutil.ReadFile(filename)
|
context, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,6 +61,7 @@ func (xc *Config) Parse(filename string) (config.Configer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseData xml data
|
// ParseData xml data
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (xc *Config) ParseData(data []byte) (config.Configer, error) {
|
func (xc *Config) ParseData(data []byte) (config.Configer, error) {
|
||||||
x := &ConfigContainer{data: make(map[string]interface{})}
|
x := &ConfigContainer{data: make(map[string]interface{})}
|
||||||
|
|
||||||
@ -73,12 +76,14 @@ func (xc *Config) ParseData(data []byte) (config.Configer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConfigContainer A Config represents the xml configuration.
|
// ConfigContainer A Config represents the xml configuration.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type ConfigContainer struct {
|
type ConfigContainer struct {
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
// Bool returns the boolean value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Bool(key string) (bool, error) {
|
func (c *ConfigContainer) Bool(key string) (bool, error) {
|
||||||
if v := c.data[key]; v != nil {
|
if v := c.data[key]; v != nil {
|
||||||
return config.ParseBool(v)
|
return config.ParseBool(v)
|
||||||
@ -88,6 +93,7 @@ func (c *ConfigContainer) Bool(key string) (bool, error) {
|
|||||||
|
|
||||||
// DefaultBool return the bool value if has no error
|
// DefaultBool return the bool value if has no error
|
||||||
// otherwise return the defaultval
|
// otherwise return the defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
||||||
v, err := c.Bool(key)
|
v, err := c.Bool(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -97,12 +103,14 @@ func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the integer value for a given key.
|
// Int returns the integer value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Int(key string) (int, error) {
|
func (c *ConfigContainer) Int(key string) (int, error) {
|
||||||
return strconv.Atoi(c.data[key].(string))
|
return strconv.Atoi(c.data[key].(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultInt returns the integer value for a given key.
|
// DefaultInt returns the integer value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
||||||
v, err := c.Int(key)
|
v, err := c.Int(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -112,12 +120,14 @@ func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int64 returns the int64 value for a given key.
|
// Int64 returns the int64 value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Int64(key string) (int64, error) {
|
func (c *ConfigContainer) Int64(key string) (int64, error) {
|
||||||
return strconv.ParseInt(c.data[key].(string), 10, 64)
|
return strconv.ParseInt(c.data[key].(string), 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultInt64 returns the int64 value for a given key.
|
// DefaultInt64 returns the int64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
||||||
v, err := c.Int64(key)
|
v, err := c.Int64(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -128,12 +138,14 @@ func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Float returns the float value for a given key.
|
// Float returns the float value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Float(key string) (float64, error) {
|
func (c *ConfigContainer) Float(key string) (float64, error) {
|
||||||
return strconv.ParseFloat(c.data[key].(string), 64)
|
return strconv.ParseFloat(c.data[key].(string), 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultFloat returns the float64 value for a given key.
|
// DefaultFloat returns the float64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
||||||
v, err := c.Float(key)
|
v, err := c.Float(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -143,6 +155,7 @@ func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string value for a given key.
|
// String returns the string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) String(key string) string {
|
func (c *ConfigContainer) String(key string) string {
|
||||||
if v, ok := c.data[key].(string); ok {
|
if v, ok := c.data[key].(string); ok {
|
||||||
return v
|
return v
|
||||||
@ -152,6 +165,7 @@ func (c *ConfigContainer) String(key string) string {
|
|||||||
|
|
||||||
// DefaultString returns the string value for a given key.
|
// DefaultString returns the string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -161,6 +175,7 @@ func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Strings(key string) []string {
|
func (c *ConfigContainer) Strings(key string) []string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -171,6 +186,7 @@ func (c *ConfigContainer) Strings(key string) []string {
|
|||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@ -180,6 +196,7 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSection returns map for the given section
|
// GetSection returns map for the given section
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
|
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
|
||||||
if v, ok := c.data[section].(map[string]interface{}); ok {
|
if v, ok := c.data[section].(map[string]interface{}); ok {
|
||||||
mapstr := make(map[string]string)
|
mapstr := make(map[string]string)
|
||||||
@ -192,6 +209,7 @@ func (c *ConfigContainer) GetSection(section string) (map[string]string, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveConfigFile save the config into file
|
// SaveConfigFile save the config into file
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
||||||
// Write configuration file by filename.
|
// Write configuration file by filename.
|
||||||
f, err := os.Create(filename)
|
f, err := os.Create(filename)
|
||||||
@ -208,6 +226,7 @@ func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set writes a new value for key.
|
// Set writes a new value for key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Set(key, val string) error {
|
func (c *ConfigContainer) Set(key, val string) error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
@ -216,6 +235,7 @@ func (c *ConfigContainer) Set(key, val string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DIY returns the raw value by a given key.
|
// DIY returns the raw value by a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
|
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
|
||||||
if v, ok := c.data[key]; ok {
|
if v, ok := c.data[key]; ok {
|
||||||
return v, nil
|
return v, nil
|
||||||
|
@ -45,9 +45,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Config is a yaml config parser and implements Config interface.
|
// Config is a yaml config parser and implements Config interface.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type Config struct{}
|
type Config struct{}
|
||||||
|
|
||||||
// Parse returns a ConfigContainer with parsed yaml config map.
|
// Parse returns a ConfigContainer with parsed yaml config map.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (yaml *Config) Parse(filename string) (y config.Configer, err error) {
|
func (yaml *Config) Parse(filename string) (y config.Configer, err error) {
|
||||||
cnf, err := ReadYmlReader(filename)
|
cnf, err := ReadYmlReader(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -60,6 +62,7 @@ func (yaml *Config) Parse(filename string) (y config.Configer, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseData parse yaml data
|
// ParseData parse yaml data
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (yaml *Config) ParseData(data []byte) (config.Configer, error) {
|
func (yaml *Config) ParseData(data []byte) (config.Configer, error) {
|
||||||
cnf, err := parseYML(data)
|
cnf, err := parseYML(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -73,6 +76,7 @@ func (yaml *Config) ParseData(data []byte) (config.Configer, error) {
|
|||||||
|
|
||||||
// ReadYmlReader Read yaml file to map.
|
// ReadYmlReader Read yaml file to map.
|
||||||
// if json like, use json package, unless goyaml2 package.
|
// if json like, use json package, unless goyaml2 package.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
|
func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
|
||||||
buf, err := ioutil.ReadFile(path)
|
buf, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -117,12 +121,14 @@ func parseYML(buf []byte) (cnf map[string]interface{}, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConfigContainer A Config represents the yaml configuration.
|
// ConfigContainer A Config represents the yaml configuration.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
type ConfigContainer struct {
|
type ConfigContainer struct {
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
// Bool returns the boolean value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Bool(key string) (bool, error) {
|
func (c *ConfigContainer) Bool(key string) (bool, error) {
|
||||||
v, err := c.getData(key)
|
v, err := c.getData(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -133,6 +139,7 @@ func (c *ConfigContainer) Bool(key string) (bool, error) {
|
|||||||
|
|
||||||
// DefaultBool return the bool value if has no error
|
// DefaultBool return the bool value if has no error
|
||||||
// otherwise return the defaultval
|
// otherwise return the defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
||||||
v, err := c.Bool(key)
|
v, err := c.Bool(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -142,6 +149,7 @@ func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the integer value for a given key.
|
// Int returns the integer value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Int(key string) (int, error) {
|
func (c *ConfigContainer) Int(key string) (int, error) {
|
||||||
if v, err := c.getData(key); err != nil {
|
if v, err := c.getData(key); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -155,6 +163,7 @@ func (c *ConfigContainer) Int(key string) (int, error) {
|
|||||||
|
|
||||||
// DefaultInt returns the integer value for a given key.
|
// DefaultInt returns the integer value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
||||||
v, err := c.Int(key)
|
v, err := c.Int(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -164,6 +173,7 @@ func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Int64 returns the int64 value for a given key.
|
// Int64 returns the int64 value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Int64(key string) (int64, error) {
|
func (c *ConfigContainer) Int64(key string) (int64, error) {
|
||||||
if v, err := c.getData(key); err != nil {
|
if v, err := c.getData(key); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -175,6 +185,7 @@ func (c *ConfigContainer) Int64(key string) (int64, error) {
|
|||||||
|
|
||||||
// DefaultInt64 returns the int64 value for a given key.
|
// DefaultInt64 returns the int64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
||||||
v, err := c.Int64(key)
|
v, err := c.Int64(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -184,6 +195,7 @@ func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Float returns the float value for a given key.
|
// Float returns the float value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Float(key string) (float64, error) {
|
func (c *ConfigContainer) Float(key string) (float64, error) {
|
||||||
if v, err := c.getData(key); err != nil {
|
if v, err := c.getData(key); err != nil {
|
||||||
return 0.0, err
|
return 0.0, err
|
||||||
@ -199,6 +211,7 @@ func (c *ConfigContainer) Float(key string) (float64, error) {
|
|||||||
|
|
||||||
// DefaultFloat returns the float64 value for a given key.
|
// DefaultFloat returns the float64 value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
||||||
v, err := c.Float(key)
|
v, err := c.Float(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -208,6 +221,7 @@ func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string value for a given key.
|
// String returns the string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) String(key string) string {
|
func (c *ConfigContainer) String(key string) string {
|
||||||
if v, err := c.getData(key); err == nil {
|
if v, err := c.getData(key); err == nil {
|
||||||
if vv, ok := v.(string); ok {
|
if vv, ok := v.(string); ok {
|
||||||
@ -219,6 +233,7 @@ func (c *ConfigContainer) String(key string) string {
|
|||||||
|
|
||||||
// DefaultString returns the string value for a given key.
|
// DefaultString returns the string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -228,6 +243,7 @@ func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Strings(key string) []string {
|
func (c *ConfigContainer) Strings(key string) []string {
|
||||||
v := c.String(key)
|
v := c.String(key)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
@ -238,6 +254,7 @@ func (c *ConfigContainer) Strings(key string) []string {
|
|||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaultval
|
// if err != nil return defaultval
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@ -247,6 +264,7 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSection returns map for the given section
|
// GetSection returns map for the given section
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
|
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
|
||||||
|
|
||||||
if v, ok := c.data[section]; ok {
|
if v, ok := c.data[section]; ok {
|
||||||
@ -256,6 +274,7 @@ func (c *ConfigContainer) GetSection(section string) (map[string]string, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveConfigFile save the config into file
|
// SaveConfigFile save the config into file
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
||||||
// Write configuration file by filename.
|
// Write configuration file by filename.
|
||||||
f, err := os.Create(filename)
|
f, err := os.Create(filename)
|
||||||
@ -268,6 +287,7 @@ func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set writes a new value for key.
|
// Set writes a new value for key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) Set(key, val string) error {
|
func (c *ConfigContainer) Set(key, val string) error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
@ -276,6 +296,7 @@ func (c *ConfigContainer) Set(key, val string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DIY returns the raw value by a given key.
|
// DIY returns the raw value by a given key.
|
||||||
|
// Deprecated: using pkg/config, we will delete this in v2.1.0
|
||||||
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
|
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
|
||||||
return c.getData(key)
|
return c.getData(key)
|
||||||
}
|
}
|
||||||
|
3
go.mod
3
go.mod
@ -31,6 +31,9 @@ require (
|
|||||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect
|
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect
|
||||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
|
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
|
||||||
|
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c
|
||||||
|
google.golang.org/grpc v1.31.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.8
|
gopkg.in/yaml.v2 v2.2.8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ func createDefaultCookie() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaultSetting Overwrite default settings
|
// SetDefaultSetting Overwrite default settings
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func SetDefaultSetting(setting BeegoHTTPSettings) {
|
func SetDefaultSetting(setting BeegoHTTPSettings) {
|
||||||
settingMutex.Lock()
|
settingMutex.Lock()
|
||||||
defer settingMutex.Unlock()
|
defer settingMutex.Unlock()
|
||||||
@ -81,6 +82,7 @@ func SetDefaultSetting(setting BeegoHTTPSettings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewBeegoRequest return *BeegoHttpRequest with specific method
|
// NewBeegoRequest return *BeegoHttpRequest with specific method
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
||||||
var resp http.Response
|
var resp http.Response
|
||||||
u, err := url.Parse(rawurl)
|
u, err := url.Parse(rawurl)
|
||||||
@ -106,31 +108,37 @@ func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns *BeegoHttpRequest with GET method.
|
// Get returns *BeegoHttpRequest with GET method.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func Get(url string) *BeegoHTTPRequest {
|
func Get(url string) *BeegoHTTPRequest {
|
||||||
return NewBeegoRequest(url, "GET")
|
return NewBeegoRequest(url, "GET")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post returns *BeegoHttpRequest with POST method.
|
// Post returns *BeegoHttpRequest with POST method.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func Post(url string) *BeegoHTTPRequest {
|
func Post(url string) *BeegoHTTPRequest {
|
||||||
return NewBeegoRequest(url, "POST")
|
return NewBeegoRequest(url, "POST")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put returns *BeegoHttpRequest with PUT method.
|
// Put returns *BeegoHttpRequest with PUT method.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func Put(url string) *BeegoHTTPRequest {
|
func Put(url string) *BeegoHTTPRequest {
|
||||||
return NewBeegoRequest(url, "PUT")
|
return NewBeegoRequest(url, "PUT")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete returns *BeegoHttpRequest DELETE method.
|
// Delete returns *BeegoHttpRequest DELETE method.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func Delete(url string) *BeegoHTTPRequest {
|
func Delete(url string) *BeegoHTTPRequest {
|
||||||
return NewBeegoRequest(url, "DELETE")
|
return NewBeegoRequest(url, "DELETE")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head returns *BeegoHttpRequest with HEAD method.
|
// Head returns *BeegoHttpRequest with HEAD method.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func Head(url string) *BeegoHTTPRequest {
|
func Head(url string) *BeegoHTTPRequest {
|
||||||
return NewBeegoRequest(url, "HEAD")
|
return NewBeegoRequest(url, "HEAD")
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeegoHTTPSettings is the http.Client setting
|
// BeegoHTTPSettings is the http.Client setting
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
type BeegoHTTPSettings struct {
|
type BeegoHTTPSettings struct {
|
||||||
ShowDebug bool
|
ShowDebug bool
|
||||||
UserAgent string
|
UserAgent string
|
||||||
@ -148,6 +156,7 @@ type BeegoHTTPSettings struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
|
// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
type BeegoHTTPRequest struct {
|
type BeegoHTTPRequest struct {
|
||||||
url string
|
url string
|
||||||
req *http.Request
|
req *http.Request
|
||||||
@ -160,35 +169,41 @@ type BeegoHTTPRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRequest return the request object
|
// GetRequest return the request object
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
|
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
|
||||||
return b.req
|
return b.req
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting Change request settings
|
// Setting Change request settings
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
|
||||||
b.setting = setting
|
b.setting = setting
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.
|
// SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetBasicAuth(username, password string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetBasicAuth(username, password string) *BeegoHTTPRequest {
|
||||||
b.req.SetBasicAuth(username, password)
|
b.req.SetBasicAuth(username, password)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEnableCookie sets enable/disable cookiejar
|
// SetEnableCookie sets enable/disable cookiejar
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetEnableCookie(enable bool) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetEnableCookie(enable bool) *BeegoHTTPRequest {
|
||||||
b.setting.EnableCookie = enable
|
b.setting.EnableCookie = enable
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUserAgent sets User-Agent header field
|
// SetUserAgent sets User-Agent header field
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetUserAgent(useragent string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetUserAgent(useragent string) *BeegoHTTPRequest {
|
||||||
b.setting.UserAgent = useragent
|
b.setting.UserAgent = useragent
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug sets show debug or not when executing request.
|
// Debug sets show debug or not when executing request.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
|
||||||
b.setting.ShowDebug = isdebug
|
b.setting.ShowDebug = isdebug
|
||||||
return b
|
return b
|
||||||
@ -198,28 +213,33 @@ func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
|
|||||||
// default is 0 means no retried.
|
// default is 0 means no retried.
|
||||||
// -1 means retried forever.
|
// -1 means retried forever.
|
||||||
// others means retried times.
|
// others means retried times.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
|
||||||
b.setting.Retries = times
|
b.setting.Retries = times
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
|
||||||
b.setting.RetryDelay = delay
|
b.setting.RetryDelay = delay
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// DumpBody setting whether need to Dump the Body.
|
// DumpBody setting whether need to Dump the Body.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
|
||||||
b.setting.DumpBody = isdump
|
b.setting.DumpBody = isdump
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// DumpRequest return the DumpRequest
|
// DumpRequest return the DumpRequest
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) DumpRequest() []byte {
|
func (b *BeegoHTTPRequest) DumpRequest() []byte {
|
||||||
return b.dump
|
return b.dump
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTimeout sets connect time out and read-write time out for BeegoRequest.
|
// SetTimeout sets connect time out and read-write time out for BeegoRequest.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest {
|
||||||
b.setting.ConnectTimeout = connectTimeout
|
b.setting.ConnectTimeout = connectTimeout
|
||||||
b.setting.ReadWriteTimeout = readWriteTimeout
|
b.setting.ReadWriteTimeout = readWriteTimeout
|
||||||
@ -227,18 +247,21 @@ func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Dura
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetTLSClientConfig sets tls connection configurations if visiting https url.
|
// SetTLSClientConfig sets tls connection configurations if visiting https url.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
|
||||||
b.setting.TLSClientConfig = config
|
b.setting.TLSClientConfig = config
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header add header item string in request.
|
// Header add header item string in request.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
|
||||||
b.req.Header.Set(key, value)
|
b.req.Header.Set(key, value)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHost set the request host
|
// SetHost set the request host
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
|
||||||
b.req.Host = host
|
b.req.Host = host
|
||||||
return b
|
return b
|
||||||
@ -246,6 +269,7 @@ func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
|
|||||||
|
|
||||||
// SetProtocolVersion Set the protocol version for incoming requests.
|
// SetProtocolVersion Set the protocol version for incoming requests.
|
||||||
// Client requests always use HTTP/1.1.
|
// Client requests always use HTTP/1.1.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
||||||
if len(vers) == 0 {
|
if len(vers) == 0 {
|
||||||
vers = "HTTP/1.1"
|
vers = "HTTP/1.1"
|
||||||
@ -262,12 +286,14 @@ func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetCookie add cookie into request.
|
// SetCookie add cookie into request.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
|
||||||
b.req.Header.Add("Cookie", cookie.String())
|
b.req.Header.Add("Cookie", cookie.String())
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTransport set the setting transport
|
// SetTransport set the setting transport
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
|
||||||
b.setting.Transport = transport
|
b.setting.Transport = transport
|
||||||
return b
|
return b
|
||||||
@ -280,6 +306,7 @@ func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPR
|
|||||||
// u, _ := url.ParseRequestURI("http://127.0.0.1:8118")
|
// u, _ := url.ParseRequestURI("http://127.0.0.1:8118")
|
||||||
// return u, nil
|
// return u, nil
|
||||||
// }
|
// }
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) *BeegoHTTPRequest {
|
||||||
b.setting.Proxy = proxy
|
b.setting.Proxy = proxy
|
||||||
return b
|
return b
|
||||||
@ -289,6 +316,7 @@ func (b *BeegoHTTPRequest) SetProxy(proxy func(*http.Request) (*url.URL, error))
|
|||||||
//
|
//
|
||||||
// If CheckRedirect is nil, the Client uses its default policy,
|
// If CheckRedirect is nil, the Client uses its default policy,
|
||||||
// which is to stop after 10 consecutive requests.
|
// which is to stop after 10 consecutive requests.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) SetCheckRedirect(redirect func(req *http.Request, via []*http.Request) error) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetCheckRedirect(redirect func(req *http.Request, via []*http.Request) error) *BeegoHTTPRequest {
|
||||||
b.setting.CheckRedirect = redirect
|
b.setting.CheckRedirect = redirect
|
||||||
return b
|
return b
|
||||||
@ -296,6 +324,7 @@ func (b *BeegoHTTPRequest) SetCheckRedirect(redirect func(req *http.Request, via
|
|||||||
|
|
||||||
// Param adds query param in to request.
|
// Param adds query param in to request.
|
||||||
// params build query string as ?key1=value1&key2=value2...
|
// params build query string as ?key1=value1&key2=value2...
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
||||||
if param, ok := b.params[key]; ok {
|
if param, ok := b.params[key]; ok {
|
||||||
b.params[key] = append(param, value)
|
b.params[key] = append(param, value)
|
||||||
@ -306,6 +335,7 @@ func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PostFile add a post file to the request
|
// PostFile add a post file to the request
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
|
||||||
b.files[formname] = filename
|
b.files[formname] = filename
|
||||||
return b
|
return b
|
||||||
@ -313,6 +343,7 @@ func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest
|
|||||||
|
|
||||||
// Body adds request raw body.
|
// Body adds request raw body.
|
||||||
// it supports string and []byte.
|
// it supports string and []byte.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
||||||
switch t := data.(type) {
|
switch t := data.(type) {
|
||||||
case string:
|
case string:
|
||||||
@ -328,6 +359,7 @@ func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XMLBody adds request raw body encoding by XML.
|
// XMLBody adds request raw body encoding by XML.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||||
if b.req.Body == nil && obj != nil {
|
if b.req.Body == nil && obj != nil {
|
||||||
byts, err := xml.Marshal(obj)
|
byts, err := xml.Marshal(obj)
|
||||||
@ -342,6 +374,7 @@ func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// YAMLBody adds request raw body encoding by YAML.
|
// YAMLBody adds request raw body encoding by YAML.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||||
if b.req.Body == nil && obj != nil {
|
if b.req.Body == nil && obj != nil {
|
||||||
byts, err := yaml.Marshal(obj)
|
byts, err := yaml.Marshal(obj)
|
||||||
@ -356,6 +389,7 @@ func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JSONBody adds request raw body encoding by JSON.
|
// JSONBody adds request raw body encoding by JSON.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||||
if b.req.Body == nil && obj != nil {
|
if b.req.Body == nil && obj != nil {
|
||||||
byts, err := json.Marshal(obj)
|
byts, err := json.Marshal(obj)
|
||||||
@ -438,6 +472,7 @@ func (b *BeegoHTTPRequest) getResponse() (*http.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DoRequest will do the client.Do
|
// DoRequest will do the client.Do
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
|
func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
|
||||||
var paramBody string
|
var paramBody string
|
||||||
if len(b.params) > 0 {
|
if len(b.params) > 0 {
|
||||||
@ -531,6 +566,7 @@ func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
|
|||||||
|
|
||||||
// String returns the body string in response.
|
// String returns the body string in response.
|
||||||
// it calls Response inner.
|
// it calls Response inner.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) String() (string, error) {
|
func (b *BeegoHTTPRequest) String() (string, error) {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -542,6 +578,7 @@ func (b *BeegoHTTPRequest) String() (string, error) {
|
|||||||
|
|
||||||
// Bytes returns the body []byte in response.
|
// Bytes returns the body []byte in response.
|
||||||
// it calls Response inner.
|
// it calls Response inner.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
||||||
if b.body != nil {
|
if b.body != nil {
|
||||||
return b.body, nil
|
return b.body, nil
|
||||||
@ -568,6 +605,7 @@ func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
|||||||
|
|
||||||
// ToFile saves the body data in response to one file.
|
// ToFile saves the body data in response to one file.
|
||||||
// it calls Response inner.
|
// it calls Response inner.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
||||||
resp, err := b.getResponse()
|
resp, err := b.getResponse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -608,6 +646,7 @@ func pathExistAndMkdir(filename string) (err error) {
|
|||||||
|
|
||||||
// ToJSON returns the map that marshals from the body bytes as json in response .
|
// ToJSON returns the map that marshals from the body bytes as json in response .
|
||||||
// it calls Response inner.
|
// it calls Response inner.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -618,6 +657,7 @@ func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
|||||||
|
|
||||||
// ToXML returns the map that marshals from the body bytes as xml in response .
|
// ToXML returns the map that marshals from the body bytes as xml in response .
|
||||||
// it calls Response inner.
|
// it calls Response inner.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -628,6 +668,7 @@ func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
|||||||
|
|
||||||
// ToYAML returns the map that marshals from the body bytes as yaml in response .
|
// ToYAML returns the map that marshals from the body bytes as yaml in response .
|
||||||
// it calls Response inner.
|
// it calls Response inner.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -637,11 +678,13 @@ func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Response executes request client gets response mannually.
|
// Response executes request client gets response mannually.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
|
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
|
||||||
return b.getResponse()
|
return b.getResponse()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeoutDialer returns functions of connection dialer with timeout settings for http.Transport Dial field.
|
// TimeoutDialer returns functions of connection dialer with timeout settings for http.Transport Dial field.
|
||||||
|
// Deprecated: using pkg/httplib, we will delete this in v2.1.0
|
||||||
func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) {
|
func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) {
|
||||||
return func(netw, addr string) (net.Conn, error) {
|
return func(netw, addr string) (net.Conn, error) {
|
||||||
conn, err := net.DialTimeout(netw, addr, cTimeout)
|
conn, err := net.DialTimeout(netw, addr, cTimeout)
|
||||||
|
@ -97,6 +97,7 @@ func initBeforeHTTPRun() {
|
|||||||
registerTemplate,
|
registerTemplate,
|
||||||
registerAdmin,
|
registerAdmin,
|
||||||
registerGzip,
|
registerGzip,
|
||||||
|
registerCommentRouter,
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, hk := range hooks {
|
for _, hk := range hooks {
|
||||||
|
22
pkg/cache/cache.go
vendored
22
pkg/cache/cache.go
vendored
@ -47,23 +47,23 @@ import (
|
|||||||
// c.Incr("counter") // now is 2
|
// c.Incr("counter") // now is 2
|
||||||
// count := c.Get("counter").(int)
|
// count := c.Get("counter").(int)
|
||||||
type Cache interface {
|
type Cache interface {
|
||||||
// get cached value by key.
|
// Get a cached value by key.
|
||||||
Get(key string) interface{}
|
Get(key string) interface{}
|
||||||
// GetMulti is a batch version of Get.
|
// GetMulti is a batch version of Get.
|
||||||
GetMulti(keys []string) []interface{}
|
GetMulti(keys []string) []interface{}
|
||||||
// set cached value with key and expire time.
|
// Set a cached value with key and expire time.
|
||||||
Put(key string, val interface{}, timeout time.Duration) error
|
Put(key string, val interface{}, timeout time.Duration) error
|
||||||
// delete cached value by key.
|
// Delete cached value by key.
|
||||||
Delete(key string) error
|
Delete(key string) error
|
||||||
// increase cached int value by key, as a counter.
|
// Increment a cached int value by key, as a counter.
|
||||||
Incr(key string) error
|
Incr(key string) error
|
||||||
// decrease cached int value by key, as a counter.
|
// Decrement a cached int value by key, as a counter.
|
||||||
Decr(key string) error
|
Decr(key string) error
|
||||||
// check if cached value exists or not.
|
// Check if a cached value exists or not.
|
||||||
IsExist(key string) bool
|
IsExist(key string) bool
|
||||||
// clear all cache.
|
// Clear all cache.
|
||||||
ClearAll() error
|
ClearAll() error
|
||||||
// start gc routine based on config string settings.
|
// Start gc routine based on config string settings.
|
||||||
StartAndGC(config string) error
|
StartAndGC(config string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,9 +85,9 @@ func Register(name string, adapter Instance) {
|
|||||||
adapters[name] = adapter
|
adapters[name] = adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCache Create a new cache driver by adapter name and config string.
|
// NewCache creates a new cache driver by adapter name and config string.
|
||||||
// config need to be correct JSON as string: {"interval":360}.
|
// config: must be in JSON format such as {"interval":360}.
|
||||||
// it will start gc automatically.
|
// Starts gc automatically.
|
||||||
func NewCache(adapterName, config string) (adapter Cache, err error) {
|
func NewCache(adapterName, config string) (adapter Cache, err error) {
|
||||||
instanceFunc, ok := adapters[adapterName]
|
instanceFunc, ok := adapters[adapterName]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
2
pkg/cache/file.go
vendored
2
pkg/cache/file.go
vendored
@ -54,7 +54,7 @@ type FileCache struct {
|
|||||||
EmbedExpiry int
|
EmbedExpiry int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFileCache cerates a new file cache with no config.
|
// NewFileCache creates a new file cache with no config.
|
||||||
// The level and expiry need to be set in the method StartAndGC as config string.
|
// The level and expiry need to be set in the method StartAndGC as config string.
|
||||||
func NewFileCache() Cache {
|
func NewFileCache() Cache {
|
||||||
// return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
|
// return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
|
||||||
|
22
pkg/cache/memcache/memcache.go
vendored
22
pkg/cache/memcache/memcache.go
vendored
@ -46,7 +46,7 @@ type Cache struct {
|
|||||||
conninfo []string
|
conninfo []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMemCache create new memcache adapter.
|
// NewMemCache creates a new memcache adapter.
|
||||||
func NewMemCache() cache.Cache {
|
func NewMemCache() cache.Cache {
|
||||||
return &Cache{}
|
return &Cache{}
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ func (rc *Cache) Get(key string) interface{} {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMulti get value from memcache.
|
// GetMulti gets a value from a key in memcache.
|
||||||
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
||||||
size := len(keys)
|
size := len(keys)
|
||||||
var rv []interface{}
|
var rv []interface{}
|
||||||
@ -89,7 +89,7 @@ func (rc *Cache) GetMulti(keys []string) []interface{} {
|
|||||||
return rv
|
return rv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put put value to memcache.
|
// Put puts a value into memcache.
|
||||||
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -107,7 +107,7 @@ func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
|||||||
return rc.conn.Set(&item)
|
return rc.conn.Set(&item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete delete value in memcache.
|
// Delete deletes a value in memcache.
|
||||||
func (rc *Cache) Delete(key string) error {
|
func (rc *Cache) Delete(key string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -117,7 +117,7 @@ func (rc *Cache) Delete(key string) error {
|
|||||||
return rc.conn.Delete(key)
|
return rc.conn.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incr increase counter.
|
// Incr increases counter.
|
||||||
func (rc *Cache) Incr(key string) error {
|
func (rc *Cache) Incr(key string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -128,7 +128,7 @@ func (rc *Cache) Incr(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decr decrease counter.
|
// Decr decreases counter.
|
||||||
func (rc *Cache) Decr(key string) error {
|
func (rc *Cache) Decr(key string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -139,7 +139,7 @@ func (rc *Cache) Decr(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsExist check value exists in memcache.
|
// IsExist checks if a value exists in memcache.
|
||||||
func (rc *Cache) IsExist(key string) bool {
|
func (rc *Cache) IsExist(key string) bool {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -150,7 +150,7 @@ func (rc *Cache) IsExist(key string) bool {
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearAll clear all cached in memcache.
|
// ClearAll clears all cache in memcache.
|
||||||
func (rc *Cache) ClearAll() error {
|
func (rc *Cache) ClearAll() error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -160,9 +160,9 @@ func (rc *Cache) ClearAll() error {
|
|||||||
return rc.conn.FlushAll()
|
return rc.conn.FlushAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartAndGC start memcache adapter.
|
// StartAndGC starts the memcache adapter.
|
||||||
// config string is like {"conn":"connection info"}.
|
// config: must be in the format {"conn":"connection info"}.
|
||||||
// if connecting error, return.
|
// If an error occurs during connecting, an error is returned
|
||||||
func (rc *Cache) StartAndGC(config string) error {
|
func (rc *Cache) StartAndGC(config string) error {
|
||||||
var cf map[string]string
|
var cf map[string]string
|
||||||
json.Unmarshal([]byte(config), &cf)
|
json.Unmarshal([]byte(config), &cf)
|
||||||
|
31
pkg/cache/redis/redis.go
vendored
31
pkg/cache/redis/redis.go
vendored
@ -43,7 +43,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultKey the collection name of redis for cache adapter.
|
// The collection name of redis for the cache adapter.
|
||||||
DefaultKey = "beecacheRedis"
|
DefaultKey = "beecacheRedis"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -56,16 +56,16 @@ type Cache struct {
|
|||||||
password string
|
password string
|
||||||
maxIdle int
|
maxIdle int
|
||||||
|
|
||||||
// the timeout to a value less than the redis server's timeout.
|
// Timeout value (less than the redis server's timeout value)
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRedisCache create new redis cache with default collection name.
|
// NewRedisCache creates a new redis cache with default collection name.
|
||||||
func NewRedisCache() cache.Cache {
|
func NewRedisCache() cache.Cache {
|
||||||
return &Cache{key: DefaultKey}
|
return &Cache{key: DefaultKey}
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually do the redis cmds, args[0] must be the key name.
|
// Execute the redis commands. args[0] must be the key name
|
||||||
func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) {
|
func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return nil, errors.New("missing required arguments")
|
return nil, errors.New("missing required arguments")
|
||||||
@ -90,7 +90,7 @@ func (rc *Cache) Get(key string) interface{} {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMulti get cache from redis.
|
// GetMulti gets cache from redis.
|
||||||
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
||||||
c := rc.p.Get()
|
c := rc.p.Get()
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
@ -105,19 +105,19 @@ func (rc *Cache) GetMulti(keys []string) []interface{} {
|
|||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put put cache to redis.
|
// Put puts cache into redis.
|
||||||
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
||||||
_, err := rc.do("SETEX", key, int64(timeout/time.Second), val)
|
_, err := rc.do("SETEX", key, int64(timeout/time.Second), val)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete delete cache in redis.
|
// Delete deletes a key's cache in redis.
|
||||||
func (rc *Cache) Delete(key string) error {
|
func (rc *Cache) Delete(key string) error {
|
||||||
_, err := rc.do("DEL", key)
|
_, err := rc.do("DEL", key)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsExist check cache's existence in redis.
|
// IsExist checks cache's existence in redis.
|
||||||
func (rc *Cache) IsExist(key string) bool {
|
func (rc *Cache) IsExist(key string) bool {
|
||||||
v, err := redis.Bool(rc.do("EXISTS", key))
|
v, err := redis.Bool(rc.do("EXISTS", key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,19 +126,19 @@ func (rc *Cache) IsExist(key string) bool {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incr increase counter in redis.
|
// Incr increases a key's counter in redis.
|
||||||
func (rc *Cache) Incr(key string) error {
|
func (rc *Cache) Incr(key string) error {
|
||||||
_, err := redis.Bool(rc.do("INCRBY", key, 1))
|
_, err := redis.Bool(rc.do("INCRBY", key, 1))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decr decrease counter in redis.
|
// Decr decreases a key's counter in redis.
|
||||||
func (rc *Cache) Decr(key string) error {
|
func (rc *Cache) Decr(key string) error {
|
||||||
_, err := redis.Bool(rc.do("INCRBY", key, -1))
|
_, err := redis.Bool(rc.do("INCRBY", key, -1))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearAll clean all cache in redis. delete this redis collection.
|
// ClearAll deletes all cache in the redis collection
|
||||||
func (rc *Cache) ClearAll() error {
|
func (rc *Cache) ClearAll() error {
|
||||||
cachedKeys, err := rc.Scan(rc.key + ":*")
|
cachedKeys, err := rc.Scan(rc.key + ":*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -154,7 +154,7 @@ func (rc *Cache) ClearAll() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan scan all keys matching the pattern. a better choice than `keys`
|
// Scan scans all keys matching a given pattern.
|
||||||
func (rc *Cache) Scan(pattern string) (keys []string, err error) {
|
func (rc *Cache) Scan(pattern string) (keys []string, err error) {
|
||||||
c := rc.p.Get()
|
c := rc.p.Get()
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
@ -183,10 +183,9 @@ func (rc *Cache) Scan(pattern string) (keys []string, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartAndGC start redis cache adapter.
|
// StartAndGC starts the redis cache adapter.
|
||||||
// config is like {"key":"collection key","conn":"connection info","dbNum":"0"}
|
// config: must be in this format {"key":"collection key","conn":"connection info","dbNum":"0"}
|
||||||
// the cache item in redis are stored forever,
|
// Cached items in redis are stored forever, no garbage collection happens
|
||||||
// so no gc operation.
|
|
||||||
func (rc *Cache) StartAndGC(config string) error {
|
func (rc *Cache) StartAndGC(config string) error {
|
||||||
var cf map[string]string
|
var cf map[string]string
|
||||||
json.Unmarshal([]byte(config), &cf)
|
json.Unmarshal([]byte(config), &cf)
|
||||||
|
27
pkg/cache/ssdb/ssdb.go
vendored
27
pkg/cache/ssdb/ssdb.go
vendored
@ -18,12 +18,12 @@ type Cache struct {
|
|||||||
conninfo []string
|
conninfo []string
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewSsdbCache create new ssdb adapter.
|
//NewSsdbCache creates new ssdb adapter.
|
||||||
func NewSsdbCache() cache.Cache {
|
func NewSsdbCache() cache.Cache {
|
||||||
return &Cache{}
|
return &Cache{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get get value from memcache.
|
// Get gets a key's value from memcache.
|
||||||
func (rc *Cache) Get(key string) interface{} {
|
func (rc *Cache) Get(key string) interface{} {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -37,7 +37,7 @@ func (rc *Cache) Get(key string) interface{} {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMulti get value from memcache.
|
// GetMulti gets one or keys values from memcache.
|
||||||
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
||||||
size := len(keys)
|
size := len(keys)
|
||||||
var values []interface{}
|
var values []interface{}
|
||||||
@ -63,7 +63,7 @@ func (rc *Cache) GetMulti(keys []string) []interface{} {
|
|||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
// DelMulti get value from memcache.
|
// DelMulti deletes one or more keys from memcache
|
||||||
func (rc *Cache) DelMulti(keys []string) error {
|
func (rc *Cache) DelMulti(keys []string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -74,7 +74,8 @@ func (rc *Cache) DelMulti(keys []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put put value to memcache. only support string.
|
// Put puts value into memcache.
|
||||||
|
// value: must be of type string
|
||||||
func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error {
|
func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -102,7 +103,7 @@ func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error
|
|||||||
return errors.New("bad response")
|
return errors.New("bad response")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete delete value in memcache.
|
// Delete deletes a value in memcache.
|
||||||
func (rc *Cache) Delete(key string) error {
|
func (rc *Cache) Delete(key string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -113,7 +114,7 @@ func (rc *Cache) Delete(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incr increase counter.
|
// Incr increases a key's counter.
|
||||||
func (rc *Cache) Incr(key string) error {
|
func (rc *Cache) Incr(key string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -124,7 +125,7 @@ func (rc *Cache) Incr(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decr decrease counter.
|
// Decr decrements a key's counter.
|
||||||
func (rc *Cache) Decr(key string) error {
|
func (rc *Cache) Decr(key string) error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -135,7 +136,7 @@ func (rc *Cache) Decr(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsExist check value exists in memcache.
|
// IsExist checks if a key exists in memcache.
|
||||||
func (rc *Cache) IsExist(key string) bool {
|
func (rc *Cache) IsExist(key string) bool {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -153,7 +154,7 @@ func (rc *Cache) IsExist(key string) bool {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearAll clear all cached in memcache.
|
// ClearAll clears all cached items in memcache.
|
||||||
func (rc *Cache) ClearAll() error {
|
func (rc *Cache) ClearAll() error {
|
||||||
if rc.conn == nil {
|
if rc.conn == nil {
|
||||||
if err := rc.connectInit(); err != nil {
|
if err := rc.connectInit(); err != nil {
|
||||||
@ -195,9 +196,9 @@ func (rc *Cache) Scan(keyStart string, keyEnd string, limit int) ([]string, erro
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartAndGC start memcache adapter.
|
// StartAndGC starts the memcache adapter.
|
||||||
// config string is like {"conn":"connection info"}.
|
// config: must be in the format {"conn":"connection info"}.
|
||||||
// if connecting error, return.
|
// If an error occurs during connection, an error is returned
|
||||||
func (rc *Cache) StartAndGC(config string) error {
|
func (rc *Cache) StartAndGC(config string) error {
|
||||||
var cf map[string]string
|
var cf map[string]string
|
||||||
json.Unmarshal([]byte(config), &cf)
|
json.Unmarshal([]byte(config), &cf)
|
||||||
|
@ -86,6 +86,7 @@ type WebConfig struct {
|
|||||||
TemplateLeft string
|
TemplateLeft string
|
||||||
TemplateRight string
|
TemplateRight string
|
||||||
ViewsPath string
|
ViewsPath string
|
||||||
|
CommentRouterPath string
|
||||||
EnableXSRF bool
|
EnableXSRF bool
|
||||||
XSRFKey string
|
XSRFKey string
|
||||||
XSRFExpire int
|
XSRFExpire int
|
||||||
@ -245,6 +246,7 @@ func newBConfig() *Config {
|
|||||||
TemplateLeft: "{{",
|
TemplateLeft: "{{",
|
||||||
TemplateRight: "}}",
|
TemplateRight: "}}",
|
||||||
ViewsPath: "views",
|
ViewsPath: "views",
|
||||||
|
CommentRouterPath: "controllers",
|
||||||
EnableXSRF: false,
|
EnableXSRF: false,
|
||||||
XSRFKey: "beegoxsrf",
|
XSRFKey: "beegoxsrf",
|
||||||
XSRFExpire: 0,
|
XSRFExpire: 0,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package ini
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@ -26,8 +26,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/astaxie/beego/pkg/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -47,7 +45,7 @@ type IniConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse creates a new Config and parses the file configuration from the named file.
|
// Parse creates a new Config and parses the file configuration from the named file.
|
||||||
func (ini *IniConfig) Parse(name string) (config.Configer, error) {
|
func (ini *IniConfig) Parse(name string) (Configer, error) {
|
||||||
return ini.parseFile(name)
|
return ini.parseFile(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +195,7 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
|
|||||||
val = bytes.Trim(val, `"`)
|
val = bytes.Trim(val, `"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.data[section][key] = config.ExpandValueEnv(string(val))
|
cfg.data[section][key] = ExpandValueEnv(string(val))
|
||||||
if comment.Len() > 0 {
|
if comment.Len() > 0 {
|
||||||
cfg.keyComment[section+"."+key] = comment.String()
|
cfg.keyComment[section+"."+key] = comment.String()
|
||||||
comment.Reset()
|
comment.Reset()
|
||||||
@ -210,7 +208,7 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
|
|||||||
// ParseData parse ini the data
|
// ParseData parse ini the data
|
||||||
// When include other.conf,other.conf is either absolute directory
|
// When include other.conf,other.conf is either absolute directory
|
||||||
// or under beego in default temporary directory(/tmp/beego[-username]).
|
// or under beego in default temporary directory(/tmp/beego[-username]).
|
||||||
func (ini *IniConfig) ParseData(data []byte) (config.Configer, error) {
|
func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
|
||||||
dir := "beego"
|
dir := "beego"
|
||||||
currentUser, err := user.Current()
|
currentUser, err := user.Current()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -224,7 +222,7 @@ func (ini *IniConfig) ParseData(data []byte) (config.Configer, error) {
|
|||||||
return ini.parseData(dir, data)
|
return ini.parseData(dir, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IniConfigContainer A Config represents the ini configuration.
|
// IniConfigContainer is a config which represents the ini configuration.
|
||||||
// When set and get value, support key as section:name type.
|
// When set and get value, support key as section:name type.
|
||||||
type IniConfigContainer struct {
|
type IniConfigContainer struct {
|
||||||
data map[string]map[string]string // section=> key:val
|
data map[string]map[string]string // section=> key:val
|
||||||
@ -235,7 +233,7 @@ type IniConfigContainer struct {
|
|||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
// Bool returns the boolean value for a given key.
|
||||||
func (c *IniConfigContainer) Bool(key string) (bool, error) {
|
func (c *IniConfigContainer) Bool(key string) (bool, error) {
|
||||||
return config.ParseBool(c.getdata(key))
|
return ParseBool(c.getdata(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBool returns the boolean value for a given key.
|
// DefaultBool returns the boolean value for a given key.
|
||||||
@ -502,5 +500,5 @@ func (c *IniConfigContainer) getdata(key string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
config.Register("ini", &IniConfig{})
|
Register("ini", &IniConfig{})
|
||||||
}
|
}
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package ini
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -20,8 +20,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/astaxie/beego/pkg/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIni(t *testing.T) {
|
func TestIni(t *testing.T) {
|
||||||
@ -94,7 +92,7 @@ password = ${GOPATH}
|
|||||||
}
|
}
|
||||||
f.Close()
|
f.Close()
|
||||||
defer os.Remove("testini.conf")
|
defer os.Remove("testini.conf")
|
||||||
iniconf, err := config.NewConfig("ini", "testini.conf")
|
iniconf, err := NewConfig("ini", "testini.conf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -167,7 +165,7 @@ httpport=8080
|
|||||||
name=mysql
|
name=mysql
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
cfg, err := config.NewConfigData("ini", []byte(inicontext))
|
cfg, err := NewConfigData("ini", []byte(inicontext))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
@ -66,7 +66,7 @@ func (js *JSONConfig) ParseData(data []byte) (config.Configer, error) {
|
|||||||
return x, nil
|
return x, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONConfigContainer A Config represents the json configuration.
|
// JSONConfigContainer is a config which represents the json configuration.
|
||||||
// Only when get value, support key as section:name type.
|
// Only when get value, support key as section:name type.
|
||||||
type JSONConfigContainer struct {
|
type JSONConfigContainer struct {
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
|
@ -72,7 +72,7 @@ func (xc *Config) ParseData(data []byte) (config.Configer, error) {
|
|||||||
return x, nil
|
return x, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigContainer A Config represents the xml configuration.
|
// ConfigContainer is a Config which represents the xml configuration.
|
||||||
type ConfigContainer struct {
|
type ConfigContainer struct {
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
@ -116,7 +116,7 @@ func parseYML(buf []byte) (cnf map[string]interface{}, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigContainer A Config represents the yaml configuration.
|
// ConfigContainer is a config which represents the yaml configuration.
|
||||||
type ConfigContainer struct {
|
type ConfigContainer struct {
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
|
@ -32,14 +32,14 @@ var (
|
|||||||
defaultGzipMinLength = 20
|
defaultGzipMinLength = 20
|
||||||
// Content will only be compressed if content length is either unknown or greater than gzipMinLength.
|
// Content will only be compressed if content length is either unknown or greater than gzipMinLength.
|
||||||
gzipMinLength = defaultGzipMinLength
|
gzipMinLength = defaultGzipMinLength
|
||||||
//The compression level used for deflate compression. (0-9).
|
// Compression level used for deflate compression. (0-9).
|
||||||
gzipCompressLevel int
|
gzipCompressLevel int
|
||||||
// List of HTTP methods to compress. If not set, only GET requests are compressed.
|
// List of HTTP methods to compress. If not set, only GET requests are compressed.
|
||||||
includedMethods map[string]bool
|
includedMethods map[string]bool
|
||||||
getMethodOnly bool
|
getMethodOnly bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitGzip init the gzipcompress
|
// InitGzip initializes the gzipcompress
|
||||||
func InitGzip(minLength, compressLevel int, methods []string) {
|
func InitGzip(minLength, compressLevel int, methods []string) {
|
||||||
if minLength >= 0 {
|
if minLength >= 0 {
|
||||||
gzipMinLength = minLength
|
gzipMinLength = minLength
|
||||||
@ -119,7 +119,7 @@ var (
|
|||||||
bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }},
|
bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }},
|
||||||
}
|
}
|
||||||
|
|
||||||
//according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed
|
// According to: http://tools.ietf.org/html/rfc2616#section-3.5 the deflate compress in http is zlib indeed
|
||||||
// deflate
|
// deflate
|
||||||
// The "zlib" format defined in RFC 1950 [31] in combination with
|
// The "zlib" format defined in RFC 1950 [31] in combination with
|
||||||
// the "deflate" compression mechanism described in RFC 1951 [29].
|
// the "deflate" compression mechanism described in RFC 1951 [29].
|
||||||
@ -154,8 +154,8 @@ func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string,
|
|||||||
return writeLevel(encoding, writer, bytes.NewReader(content), gzipCompressLevel)
|
return writeLevel(encoding, writer, bytes.NewReader(content), gzipCompressLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeLevel reads from reader,writes to writer by specific encoding and compress level
|
// writeLevel reads from reader and writes to writer by specific encoding and compress level.
|
||||||
// the compress level is defined by deflate package
|
// The compress level is defined by deflate package
|
||||||
func writeLevel(encoding string, writer io.Writer, reader io.Reader, level int) (bool, string, error) {
|
func writeLevel(encoding string, writer io.Writer, reader io.Reader, level int) (bool, string, error) {
|
||||||
var outputWriter resetWriter
|
var outputWriter resetWriter
|
||||||
var err error
|
var err error
|
||||||
|
@ -38,7 +38,7 @@ import (
|
|||||||
"github.com/astaxie/beego/pkg/utils"
|
"github.com/astaxie/beego/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
//commonly used mime-types
|
// Commonly used mime-types
|
||||||
const (
|
const (
|
||||||
ApplicationJSON = "application/json"
|
ApplicationJSON = "application/json"
|
||||||
ApplicationXML = "application/xml"
|
ApplicationXML = "application/xml"
|
||||||
@ -55,7 +55,7 @@ func NewContext() *Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
|
// 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.
|
// BeegoInput and BeegoOutput provides an api to operate request and response more easily.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
Input *BeegoInput
|
Input *BeegoInput
|
||||||
Output *BeegoOutput
|
Output *BeegoOutput
|
||||||
@ -64,7 +64,7 @@ type Context struct {
|
|||||||
_xsrfToken string
|
_xsrfToken string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset init Context, BeegoInput and BeegoOutput
|
// Reset initializes Context, BeegoInput and BeegoOutput
|
||||||
func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
|
func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx.Request = r
|
ctx.Request = r
|
||||||
if ctx.ResponseWriter == nil {
|
if ctx.ResponseWriter == nil {
|
||||||
@ -76,37 +76,36 @@ func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
|
|||||||
ctx._xsrfToken = ""
|
ctx._xsrfToken = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect does redirection to localurl with http header status code.
|
// Redirect redirects to localurl with http header status code.
|
||||||
func (ctx *Context) Redirect(status int, localurl string) {
|
func (ctx *Context) Redirect(status int, localurl string) {
|
||||||
http.Redirect(ctx.ResponseWriter, ctx.Request, localurl, status)
|
http.Redirect(ctx.ResponseWriter, ctx.Request, localurl, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abort stops this request.
|
// Abort stops the request.
|
||||||
// if beego.ErrorMaps exists, panic body.
|
// If beego.ErrorMaps exists, panic body.
|
||||||
func (ctx *Context) Abort(status int, body string) {
|
func (ctx *Context) Abort(status int, body string) {
|
||||||
ctx.Output.SetStatus(status)
|
ctx.Output.SetStatus(status)
|
||||||
panic(body)
|
panic(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteString Write string to response body.
|
// WriteString writes a string to response body.
|
||||||
// it sends response body.
|
|
||||||
func (ctx *Context) WriteString(content string) {
|
func (ctx *Context) WriteString(content string) {
|
||||||
ctx.ResponseWriter.Write([]byte(content))
|
ctx.ResponseWriter.Write([]byte(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCookie Get cookie from request by a given key.
|
// GetCookie gets a cookie from a request for a given key.
|
||||||
// It's alias of BeegoInput.Cookie.
|
// (Alias of BeegoInput.Cookie)
|
||||||
func (ctx *Context) GetCookie(key string) string {
|
func (ctx *Context) GetCookie(key string) string {
|
||||||
return ctx.Input.Cookie(key)
|
return ctx.Input.Cookie(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCookie Set cookie for response.
|
// SetCookie sets a cookie for a response.
|
||||||
// It's alias of BeegoOutput.Cookie.
|
// (Alias of BeegoOutput.Cookie)
|
||||||
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
|
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
|
||||||
ctx.Output.Cookie(name, value, others...)
|
ctx.Output.Cookie(name, value, others...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSecureCookie Get secure cookie from request by a given key.
|
// GetSecureCookie gets a secure cookie from a request for a given key.
|
||||||
func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
|
func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
|
||||||
val := ctx.Input.Cookie(key)
|
val := ctx.Input.Cookie(key)
|
||||||
if val == "" {
|
if val == "" {
|
||||||
@ -133,7 +132,7 @@ func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
|
|||||||
return string(res), true
|
return string(res), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSecureCookie Set Secure cookie for response.
|
// SetSecureCookie sets a secure cookie for a response.
|
||||||
func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||||
vs := base64.URLEncoding.EncodeToString([]byte(value))
|
vs := base64.URLEncoding.EncodeToString([]byte(value))
|
||||||
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
|
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||||
@ -144,7 +143,7 @@ func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interf
|
|||||||
ctx.Output.Cookie(name, cookie, others...)
|
ctx.Output.Cookie(name, cookie, others...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// XSRFToken creates a xsrf token string and returns.
|
// XSRFToken creates and returns an xsrf token string
|
||||||
func (ctx *Context) XSRFToken(key string, expire int64) string {
|
func (ctx *Context) XSRFToken(key string, expire int64) string {
|
||||||
if ctx._xsrfToken == "" {
|
if ctx._xsrfToken == "" {
|
||||||
token, ok := ctx.GetSecureCookie(key, "_xsrf")
|
token, ok := ctx.GetSecureCookie(key, "_xsrf")
|
||||||
@ -157,8 +156,8 @@ func (ctx *Context) XSRFToken(key string, expire int64) string {
|
|||||||
return ctx._xsrfToken
|
return ctx._xsrfToken
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckXSRFCookie checks xsrf token in this request is valid or not.
|
// CheckXSRFCookie checks if the XSRF token in this request is valid or not.
|
||||||
// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
|
// The token can be provided in the request header in the form "X-Xsrftoken" or "X-CsrfToken"
|
||||||
// or in form field value named as "_xsrf".
|
// or in form field value named as "_xsrf".
|
||||||
func (ctx *Context) CheckXSRFCookie() bool {
|
func (ctx *Context) CheckXSRFCookie() bool {
|
||||||
token := ctx.Input.Query("_xsrf")
|
token := ctx.Input.Query("_xsrf")
|
||||||
@ -196,7 +195,7 @@ func (ctx *Context) RenderMethodResult(result interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Response is a wrapper for the http.ResponseWriter
|
// Response is a wrapper for the http.ResponseWriter
|
||||||
//started set to true if response was written to then don't execute other handler
|
// Started: if true, response was already written to so the other handler will not be executed
|
||||||
type Response struct {
|
type Response struct {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
Started bool
|
Started bool
|
||||||
@ -210,16 +209,16 @@ func (r *Response) reset(rw http.ResponseWriter) {
|
|||||||
r.Started = false
|
r.Started = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the data to the connection as part of an HTTP reply,
|
// Write writes the data to the connection as part of a HTTP reply,
|
||||||
// and sets `started` to true.
|
// and sets `Started` to true.
|
||||||
// started means the response has sent out.
|
// Started: if true, the response was already sent
|
||||||
func (r *Response) Write(p []byte) (int, error) {
|
func (r *Response) Write(p []byte) (int, error) {
|
||||||
r.Started = true
|
r.Started = true
|
||||||
return r.ResponseWriter.Write(p)
|
return r.ResponseWriter.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeader sends an HTTP response header with status code,
|
// WriteHeader sends a HTTP response header with status code,
|
||||||
// and sets `started` to true.
|
// and sets `Started` to true.
|
||||||
func (r *Response) WriteHeader(code int) {
|
func (r *Response) WriteHeader(code int) {
|
||||||
if r.Status > 0 {
|
if r.Status > 0 {
|
||||||
//prevent multiple response.WriteHeader calls
|
//prevent multiple response.WriteHeader calls
|
||||||
|
@ -43,7 +43,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// BeegoInput operates the http request header, data, cookie and body.
|
// BeegoInput operates the http request header, data, cookie and body.
|
||||||
// it also contains router params and current session.
|
// Contains router params and current session.
|
||||||
type BeegoInput struct {
|
type BeegoInput struct {
|
||||||
Context *Context
|
Context *Context
|
||||||
CruSession session.Store
|
CruSession session.Store
|
||||||
@ -56,7 +56,7 @@ type BeegoInput struct {
|
|||||||
RunController reflect.Type
|
RunController reflect.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInput return BeegoInput generated by Context.
|
// NewInput returns the BeegoInput generated by context.
|
||||||
func NewInput() *BeegoInput {
|
func NewInput() *BeegoInput {
|
||||||
return &BeegoInput{
|
return &BeegoInput{
|
||||||
pnames: make([]string, 0, maxParam),
|
pnames: make([]string, 0, maxParam),
|
||||||
@ -65,7 +65,7 @@ func NewInput() *BeegoInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset init the BeegoInput
|
// Reset initializes the BeegoInput
|
||||||
func (input *BeegoInput) Reset(ctx *Context) {
|
func (input *BeegoInput) Reset(ctx *Context) {
|
||||||
input.Context = ctx
|
input.Context = ctx
|
||||||
input.CruSession = nil
|
input.CruSession = nil
|
||||||
@ -77,27 +77,27 @@ func (input *BeegoInput) Reset(ctx *Context) {
|
|||||||
input.RequestBody = []byte{}
|
input.RequestBody = []byte{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol returns request protocol name, such as HTTP/1.1 .
|
// Protocol returns the request protocol name, such as HTTP/1.1 .
|
||||||
func (input *BeegoInput) Protocol() string {
|
func (input *BeegoInput) Protocol() string {
|
||||||
return input.Context.Request.Proto
|
return input.Context.Request.Proto
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI returns full request url with query string, fragment.
|
// URI returns the full request url with query, string and fragment.
|
||||||
func (input *BeegoInput) URI() string {
|
func (input *BeegoInput) URI() string {
|
||||||
return input.Context.Request.RequestURI
|
return input.Context.Request.RequestURI
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL returns request url path (without query string, fragment).
|
// URL returns the request url path (without query, string and fragment).
|
||||||
func (input *BeegoInput) URL() string {
|
func (input *BeegoInput) URL() string {
|
||||||
return input.Context.Request.URL.EscapedPath()
|
return input.Context.Request.URL.EscapedPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Site returns base site url as scheme://domain type.
|
// Site returns the base site url as scheme://domain type.
|
||||||
func (input *BeegoInput) Site() string {
|
func (input *BeegoInput) Site() string {
|
||||||
return input.Scheme() + "://" + input.Domain()
|
return input.Scheme() + "://" + input.Domain()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scheme returns request scheme as "http" or "https".
|
// Scheme returns the request scheme as "http" or "https".
|
||||||
func (input *BeegoInput) Scheme() string {
|
func (input *BeegoInput) Scheme() string {
|
||||||
if scheme := input.Header("X-Forwarded-Proto"); scheme != "" {
|
if scheme := input.Header("X-Forwarded-Proto"); scheme != "" {
|
||||||
return scheme
|
return scheme
|
||||||
@ -111,14 +111,13 @@ func (input *BeegoInput) Scheme() string {
|
|||||||
return "https"
|
return "https"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domain returns host name.
|
// Domain returns the host name (alias of host method)
|
||||||
// Alias of Host method.
|
|
||||||
func (input *BeegoInput) Domain() string {
|
func (input *BeegoInput) Domain() string {
|
||||||
return input.Host()
|
return input.Host()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host returns host name.
|
// Host returns the host name.
|
||||||
// if no host info in request, return localhost.
|
// If no host info in request, return localhost.
|
||||||
func (input *BeegoInput) Host() string {
|
func (input *BeegoInput) Host() string {
|
||||||
if input.Context.Request.Host != "" {
|
if input.Context.Request.Host != "" {
|
||||||
if hostPart, _, err := net.SplitHostPort(input.Context.Request.Host); err == nil {
|
if hostPart, _, err := net.SplitHostPort(input.Context.Request.Host); err == nil {
|
||||||
@ -134,7 +133,7 @@ func (input *BeegoInput) Method() string {
|
|||||||
return input.Context.Request.Method
|
return input.Context.Request.Method
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is returns boolean of this request is on given method, such as Is("POST").
|
// Is returns the boolean value of this request is on given method, such as Is("POST").
|
||||||
func (input *BeegoInput) Is(method string) bool {
|
func (input *BeegoInput) Is(method string) bool {
|
||||||
return input.Method() == method
|
return input.Method() == method
|
||||||
}
|
}
|
||||||
@ -174,7 +173,7 @@ func (input *BeegoInput) IsPatch() bool {
|
|||||||
return input.Is("PATCH")
|
return input.Is("PATCH")
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAjax returns boolean of this request is generated by ajax.
|
// IsAjax returns boolean of is this request generated by ajax.
|
||||||
func (input *BeegoInput) IsAjax() bool {
|
func (input *BeegoInput) IsAjax() bool {
|
||||||
return input.Header("X-Requested-With") == "XMLHttpRequest"
|
return input.Header("X-Requested-With") == "XMLHttpRequest"
|
||||||
}
|
}
|
||||||
@ -251,7 +250,7 @@ func (input *BeegoInput) Refer() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SubDomains returns sub domain string.
|
// SubDomains returns sub domain string.
|
||||||
// if aa.bb.domain.com, returns aa.bb .
|
// if aa.bb.domain.com, returns aa.bb
|
||||||
func (input *BeegoInput) SubDomains() string {
|
func (input *BeegoInput) SubDomains() string {
|
||||||
parts := strings.Split(input.Host(), ".")
|
parts := strings.Split(input.Host(), ".")
|
||||||
if len(parts) >= 3 {
|
if len(parts) >= 3 {
|
||||||
@ -306,7 +305,7 @@ func (input *BeegoInput) Params() map[string]string {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetParam will set the param with key and value
|
// SetParam sets the param with key and value
|
||||||
func (input *BeegoInput) SetParam(key, val string) {
|
func (input *BeegoInput) SetParam(key, val string) {
|
||||||
// check if already exists
|
// check if already exists
|
||||||
for i, v := range input.pnames {
|
for i, v := range input.pnames {
|
||||||
@ -319,9 +318,8 @@ func (input *BeegoInput) SetParam(key, val string) {
|
|||||||
input.pnames = append(input.pnames, key)
|
input.pnames = append(input.pnames, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetParams clears any of the input's Params
|
// ResetParams clears any of the input's params
|
||||||
// This function is used to clear parameters so they may be reset between filter
|
// Used to clear parameters so they may be reset between filter passes.
|
||||||
// passes.
|
|
||||||
func (input *BeegoInput) ResetParams() {
|
func (input *BeegoInput) ResetParams() {
|
||||||
input.pnames = input.pnames[:0]
|
input.pnames = input.pnames[:0]
|
||||||
input.pvalues = input.pvalues[:0]
|
input.pvalues = input.pvalues[:0]
|
||||||
@ -391,7 +389,7 @@ func (input *BeegoInput) CopyBody(MaxMemory int64) []byte {
|
|||||||
return requestbody
|
return requestbody
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data return the implicit data in the input
|
// Data returns the implicit data in the input
|
||||||
func (input *BeegoInput) Data() map[interface{}]interface{} {
|
func (input *BeegoInput) Data() map[interface{}]interface{} {
|
||||||
input.dataLock.Lock()
|
input.dataLock.Lock()
|
||||||
defer input.dataLock.Unlock()
|
defer input.dataLock.Unlock()
|
||||||
@ -412,7 +410,7 @@ func (input *BeegoInput) GetData(key interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetData stores data with given key in this context.
|
// SetData stores data with given key in this context.
|
||||||
// This data are only available in this context.
|
// This data is only available in this context.
|
||||||
func (input *BeegoInput) SetData(key, val interface{}) {
|
func (input *BeegoInput) SetData(key, val interface{}) {
|
||||||
input.dataLock.Lock()
|
input.dataLock.Lock()
|
||||||
defer input.dataLock.Unlock()
|
defer input.dataLock.Unlock()
|
||||||
|
@ -42,12 +42,12 @@ type BeegoOutput struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOutput returns new BeegoOutput.
|
// NewOutput returns new BeegoOutput.
|
||||||
// it contains nothing now.
|
// Empty when initialized
|
||||||
func NewOutput() *BeegoOutput {
|
func NewOutput() *BeegoOutput {
|
||||||
return &BeegoOutput{}
|
return &BeegoOutput{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset init BeegoOutput
|
// Reset initializes BeegoOutput
|
||||||
func (output *BeegoOutput) Reset(ctx *Context) {
|
func (output *BeegoOutput) Reset(ctx *Context) {
|
||||||
output.Context = ctx
|
output.Context = ctx
|
||||||
output.Status = 0
|
output.Status = 0
|
||||||
@ -58,9 +58,9 @@ func (output *BeegoOutput) Header(key, val string) {
|
|||||||
output.Context.ResponseWriter.Header().Set(key, val)
|
output.Context.ResponseWriter.Header().Set(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body sets response body content.
|
// Body sets the response body content.
|
||||||
// if EnableGzip, compress content string.
|
// if EnableGzip, content is compressed.
|
||||||
// it sends out response body directly.
|
// Sends out response body directly.
|
||||||
func (output *BeegoOutput) Body(content []byte) error {
|
func (output *BeegoOutput) Body(content []byte) error {
|
||||||
var encoding string
|
var encoding string
|
||||||
var buf = &bytes.Buffer{}
|
var buf = &bytes.Buffer{}
|
||||||
@ -85,8 +85,8 @@ func (output *BeegoOutput) Body(content []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cookie sets cookie value via given key.
|
// Cookie sets a cookie value via given key.
|
||||||
// others are ordered as cookie's max age time, path,domain, secure and httponly.
|
// others: used to set a cookie's max age time, path,domain, secure and httponly.
|
||||||
func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
|
func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
fmt.Fprintf(&b, "%s=%s", sanitizeName(name), sanitizeValue(value))
|
fmt.Fprintf(&b, "%s=%s", sanitizeName(name), sanitizeValue(value))
|
||||||
@ -183,7 +183,7 @@ func errorRenderer(err error) Renderer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON writes json to response body.
|
// JSON writes json to the response body.
|
||||||
// if encoding is true, it converts utf-8 to \u0000 type.
|
// if encoding is true, it converts utf-8 to \u0000 type.
|
||||||
func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
|
func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
|
||||||
output.Header("Content-Type", "application/json; charset=utf-8")
|
output.Header("Content-Type", "application/json; charset=utf-8")
|
||||||
@ -204,7 +204,7 @@ func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool)
|
|||||||
return output.Body(content)
|
return output.Body(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// YAML writes yaml to response body.
|
// YAML writes yaml to the response body.
|
||||||
func (output *BeegoOutput) YAML(data interface{}) error {
|
func (output *BeegoOutput) YAML(data interface{}) error {
|
||||||
output.Header("Content-Type", "application/x-yaml; charset=utf-8")
|
output.Header("Content-Type", "application/x-yaml; charset=utf-8")
|
||||||
var content []byte
|
var content []byte
|
||||||
@ -217,7 +217,7 @@ func (output *BeegoOutput) YAML(data interface{}) error {
|
|||||||
return output.Body(content)
|
return output.Body(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP writes jsonp to response body.
|
// JSONP writes jsonp to the response body.
|
||||||
func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
|
func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
|
||||||
output.Header("Content-Type", "application/javascript; charset=utf-8")
|
output.Header("Content-Type", "application/javascript; charset=utf-8")
|
||||||
var content []byte
|
var content []byte
|
||||||
@ -243,7 +243,7 @@ func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
|
|||||||
return output.Body(callbackContent.Bytes())
|
return output.Body(callbackContent.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML writes xml string to response body.
|
// XML writes xml string to the response body.
|
||||||
func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
|
func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
|
||||||
output.Header("Content-Type", "application/xml; charset=utf-8")
|
output.Header("Content-Type", "application/xml; charset=utf-8")
|
||||||
var content []byte
|
var content []byte
|
||||||
@ -260,7 +260,7 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
|
|||||||
return output.Body(content)
|
return output.Body(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
|
// ServeFormatted serves YAML, XML or JSON, depending on the value of the Accept header
|
||||||
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
|
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
|
||||||
accept := output.Context.Input.Header("Accept")
|
accept := output.Context.Input.Header("Accept")
|
||||||
switch accept {
|
switch accept {
|
||||||
@ -274,7 +274,7 @@ func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasE
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Download forces response for download file.
|
// Download forces response for download file.
|
||||||
// it prepares the download response header automatically.
|
// Prepares the download response header automatically.
|
||||||
func (output *BeegoOutput) Download(file string, filename ...string) {
|
func (output *BeegoOutput) Download(file string, filename ...string) {
|
||||||
// check get file error, file not found or other error.
|
// check get file error, file not found or other error.
|
||||||
if _, err := os.Stat(file); err != nil {
|
if _, err := os.Stat(file); err != nil {
|
||||||
@ -323,61 +323,61 @@ func (output *BeegoOutput) ContentType(ext string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStatus sets response status code.
|
// SetStatus sets the response status code.
|
||||||
// It writes response header directly.
|
// Writes response header directly.
|
||||||
func (output *BeegoOutput) SetStatus(status int) {
|
func (output *BeegoOutput) SetStatus(status int) {
|
||||||
output.Status = status
|
output.Status = status
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsCachable returns boolean of this request is cached.
|
// IsCachable returns boolean of if this request is cached.
|
||||||
// HTTP 304 means cached.
|
// HTTP 304 means cached.
|
||||||
func (output *BeegoOutput) IsCachable() bool {
|
func (output *BeegoOutput) IsCachable() bool {
|
||||||
return output.Status >= 200 && output.Status < 300 || output.Status == 304
|
return output.Status >= 200 && output.Status < 300 || output.Status == 304
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns boolean of this request is empty.
|
// IsEmpty returns boolean of if this request is empty.
|
||||||
// HTTP 201,204 and 304 means empty.
|
// HTTP 201,204 and 304 means empty.
|
||||||
func (output *BeegoOutput) IsEmpty() bool {
|
func (output *BeegoOutput) IsEmpty() bool {
|
||||||
return output.Status == 201 || output.Status == 204 || output.Status == 304
|
return output.Status == 201 || output.Status == 204 || output.Status == 304
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOk returns boolean of this request runs well.
|
// IsOk returns boolean of if this request was ok.
|
||||||
// HTTP 200 means ok.
|
// HTTP 200 means ok.
|
||||||
func (output *BeegoOutput) IsOk() bool {
|
func (output *BeegoOutput) IsOk() bool {
|
||||||
return output.Status == 200
|
return output.Status == 200
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSuccessful returns boolean of this request runs successfully.
|
// IsSuccessful returns boolean of this request was successful.
|
||||||
// HTTP 2xx means ok.
|
// HTTP 2xx means ok.
|
||||||
func (output *BeegoOutput) IsSuccessful() bool {
|
func (output *BeegoOutput) IsSuccessful() bool {
|
||||||
return output.Status >= 200 && output.Status < 300
|
return output.Status >= 200 && output.Status < 300
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsRedirect returns boolean of this request is redirection header.
|
// IsRedirect returns boolean of if this request is redirected.
|
||||||
// HTTP 301,302,307 means redirection.
|
// HTTP 301,302,307 means redirection.
|
||||||
func (output *BeegoOutput) IsRedirect() bool {
|
func (output *BeegoOutput) IsRedirect() bool {
|
||||||
return output.Status == 301 || output.Status == 302 || output.Status == 303 || output.Status == 307
|
return output.Status == 301 || output.Status == 302 || output.Status == 303 || output.Status == 307
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsForbidden returns boolean of this request is forbidden.
|
// IsForbidden returns boolean of if this request is forbidden.
|
||||||
// HTTP 403 means forbidden.
|
// HTTP 403 means forbidden.
|
||||||
func (output *BeegoOutput) IsForbidden() bool {
|
func (output *BeegoOutput) IsForbidden() bool {
|
||||||
return output.Status == 403
|
return output.Status == 403
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNotFound returns boolean of this request is not found.
|
// IsNotFound returns boolean of if this request is not found.
|
||||||
// HTTP 404 means not found.
|
// HTTP 404 means not found.
|
||||||
func (output *BeegoOutput) IsNotFound() bool {
|
func (output *BeegoOutput) IsNotFound() bool {
|
||||||
return output.Status == 404
|
return output.Status == 404
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsClientError returns boolean of this request client sends error data.
|
// IsClientError returns boolean of if this request client sends error data.
|
||||||
// HTTP 4xx means client error.
|
// HTTP 4xx means client error.
|
||||||
func (output *BeegoOutput) IsClientError() bool {
|
func (output *BeegoOutput) IsClientError() bool {
|
||||||
return output.Status >= 400 && output.Status < 500
|
return output.Status >= 400 && output.Status < 500
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsServerError returns boolean of this server handler errors.
|
// IsServerError returns boolean of if this server handler errors.
|
||||||
// HTTP 5xx means server internal error.
|
// HTTP 5xx means server internal error.
|
||||||
func (output *BeegoOutput) IsServerError() bool {
|
func (output *BeegoOutput) IsServerError() bool {
|
||||||
return output.Status >= 500 && output.Status < 600
|
return output.Status >= 500 && output.Status < 600
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package context
|
package context
|
||||||
|
|
||||||
// Renderer defines an http response renderer
|
// Renderer defines a http response renderer
|
||||||
type Renderer interface {
|
type Renderer interface {
|
||||||
Render(ctx *Context)
|
Render(ctx *Context)
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//BadRequest indicates http error 400
|
//BadRequest indicates HTTP error 400
|
||||||
BadRequest StatusCode = http.StatusBadRequest
|
BadRequest StatusCode = http.StatusBadRequest
|
||||||
|
|
||||||
//NotFound indicates http error 404
|
//NotFound indicates HTTP error 404
|
||||||
NotFound StatusCode = http.StatusNotFound
|
NotFound StatusCode = http.StatusNotFound
|
||||||
)
|
)
|
||||||
|
|
||||||
// StatusCode sets the http response status code
|
// StatusCode sets the HTTP response status code
|
||||||
type StatusCode int
|
type StatusCode int
|
||||||
|
|
||||||
func (s StatusCode) Error() string {
|
func (s StatusCode) Error() string {
|
||||||
return strconv.Itoa(int(s))
|
return strconv.Itoa(int(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render sets the http status code
|
// Render sets the HTTP status code
|
||||||
func (s StatusCode) Render(ctx *Context) {
|
func (s StatusCode) Render(ctx *Context) {
|
||||||
ctx.Output.SetStatus(int(s))
|
ctx.Output.SetStatus(int(s))
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ type Server struct {
|
|||||||
terminalChan chan error
|
terminalChan chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve accepts incoming connections on the Listener l,
|
// Serve accepts incoming connections on the Listener l
|
||||||
// creating a new service goroutine for each.
|
// and creates a new service goroutine for each.
|
||||||
// The service goroutines read requests and then call srv.Handler to reply to them.
|
// The service goroutines read requests and then call srv.Handler to reply to them.
|
||||||
func (srv *Server) Serve() (err error) {
|
func (srv *Server) Serve() (err error) {
|
||||||
srv.state = StateRunning
|
srv.state = StateRunning
|
||||||
|
10
pkg/hooks.go
10
pkg/hooks.go
@ -102,3 +102,13 @@ func registerGzip() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerCommentRouter() error {
|
||||||
|
if BConfig.RunMode == DEV {
|
||||||
|
if err := parserPkg(filepath.Join(WorkPath, BConfig.WebConfig.CommentRouterPath)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
24
pkg/httplib/filter.go
Normal file
24
pkg/httplib/filter.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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 httplib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterChain func(next Filter) Filter
|
||||||
|
|
||||||
|
type Filter func(ctx context.Context, req *BeegoHTTPRequest) (*http.Response, error)
|
77
pkg/httplib/filter/opentracing/filter.go
Normal file
77
pkg/httplib/filter/opentracing/filter.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// 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"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
logKit "github.com/go-kit/kit/log"
|
||||||
|
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
||||||
|
"github.com/opentracing/opentracing-go"
|
||||||
|
"github.com/opentracing/opentracing-go/log"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/httplib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterChainBuilder struct {
|
||||||
|
// CustomSpanFunc users are able to custom their span
|
||||||
|
CustomSpanFunc func(span opentracing.Span, ctx context.Context,
|
||||||
|
req *httplib.BeegoHTTPRequest, resp *http.Response, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filter {
|
||||||
|
|
||||||
|
return func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
|
||||||
|
|
||||||
|
method := req.GetRequest().Method
|
||||||
|
host := req.GetRequest().URL.Host
|
||||||
|
path := req.GetRequest().URL.Path
|
||||||
|
|
||||||
|
proto := req.GetRequest().Proto
|
||||||
|
|
||||||
|
scheme := req.GetRequest().URL.Scheme
|
||||||
|
|
||||||
|
operationName := host + path + "#" + method
|
||||||
|
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
inject := opentracingKit.ContextToHTTP(opentracing.GlobalTracer(), logKit.NewNopLogger())
|
||||||
|
inject(spanCtx, req.GetRequest())
|
||||||
|
resp, err := next(spanCtx, req)
|
||||||
|
|
||||||
|
if resp != nil {
|
||||||
|
span.SetTag("status", strconv.Itoa(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
span.SetTag("method", method)
|
||||||
|
span.SetTag("host", host)
|
||||||
|
span.SetTag("path", path)
|
||||||
|
span.SetTag("proto", proto)
|
||||||
|
span.SetTag("scheme", scheme)
|
||||||
|
|
||||||
|
span.LogFields(log.String("url", req.GetRequest().URL.String()))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
span.LogFields(log.String("error", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if builder.CustomSpanFunc != nil {
|
||||||
|
builder.CustomSpanFunc(span, ctx, req, resp, err)
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
42
pkg/httplib/filter/opentracing/filter_test.go
Normal file
42
pkg/httplib/filter/opentracing/filter_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// 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"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/httplib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||||
|
next := func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: 404,
|
||||||
|
}, errors.New("hello")
|
||||||
|
}
|
||||||
|
builder := &FilterChainBuilder{}
|
||||||
|
filter := builder.FilterChain(next)
|
||||||
|
req := httplib.Get("https://github.com/notifications?query=repo%3Aastaxie%2Fbeego")
|
||||||
|
resp, err := filter(context.Background(), req)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
}
|
73
pkg/httplib/filter/prometheus/filter.go
Normal file
73
pkg/httplib/filter/prometheus/filter.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
beego "github.com/astaxie/beego/pkg"
|
||||||
|
"github.com/astaxie/beego/pkg/httplib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterChainBuilder struct {
|
||||||
|
summaryVec prometheus.ObserverVec
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filter {
|
||||||
|
|
||||||
|
builder.summaryVec = prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||||
|
Name: "beego",
|
||||||
|
Subsystem: "remote_http_request",
|
||||||
|
ConstLabels: map[string]string{
|
||||||
|
"server": beego.BConfig.ServerName,
|
||||||
|
"env": beego.BConfig.RunMode,
|
||||||
|
"appname": beego.BConfig.AppName,
|
||||||
|
},
|
||||||
|
Help: "The statics info for remote http requests",
|
||||||
|
}, []string{"proto", "scheme", "method", "host", "path", "status", "duration", "isError"})
|
||||||
|
|
||||||
|
return func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
|
||||||
|
startTime := time.Now()
|
||||||
|
resp, err := next(ctx, req)
|
||||||
|
endTime := time.Now()
|
||||||
|
go builder.report(startTime, endTime, ctx, req, resp, err)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) report(startTime time.Time, endTime time.Time,
|
||||||
|
ctx context.Context, req *httplib.BeegoHTTPRequest, resp *http.Response, err error) {
|
||||||
|
|
||||||
|
proto := req.GetRequest().Proto
|
||||||
|
|
||||||
|
scheme := req.GetRequest().URL.Scheme
|
||||||
|
method := req.GetRequest().Method
|
||||||
|
|
||||||
|
host := req.GetRequest().URL.Host
|
||||||
|
path := req.GetRequest().URL.Path
|
||||||
|
|
||||||
|
status := resp.StatusCode
|
||||||
|
|
||||||
|
dur := int(endTime.Sub(startTime) / time.Millisecond)
|
||||||
|
|
||||||
|
|
||||||
|
builder.summaryVec.WithLabelValues(proto, scheme, method, host, path,
|
||||||
|
strconv.Itoa(status), strconv.Itoa(dur), strconv.FormatBool(err == nil))
|
||||||
|
}
|
41
pkg/httplib/filter/prometheus/filter_test.go
Normal file
41
pkg/httplib/filter/prometheus/filter_test.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/httplib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||||
|
next := func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: 404,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
builder := &FilterChainBuilder{}
|
||||||
|
filter := builder.FilterChain(next)
|
||||||
|
req := httplib.Get("https://github.com/notifications?query=repo%3Aastaxie%2Fbeego")
|
||||||
|
resp, err := filter(context.Background(), req)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
@ -34,6 +34,7 @@ package httplib
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
@ -66,6 +67,11 @@ var defaultSetting = BeegoHTTPSettings{
|
|||||||
var defaultCookieJar http.CookieJar
|
var defaultCookieJar http.CookieJar
|
||||||
var settingMutex sync.Mutex
|
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.
|
// createDefaultCookie creates a global cookiejar to store cookies.
|
||||||
func createDefaultCookie() {
|
func createDefaultCookie() {
|
||||||
settingMutex.Lock()
|
settingMutex.Lock()
|
||||||
@ -73,14 +79,14 @@ func createDefaultCookie() {
|
|||||||
defaultCookieJar, _ = cookiejar.New(nil)
|
defaultCookieJar, _ = cookiejar.New(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaultSetting Overwrite default settings
|
// SetDefaultSetting overwrites default settings
|
||||||
func SetDefaultSetting(setting BeegoHTTPSettings) {
|
func SetDefaultSetting(setting BeegoHTTPSettings) {
|
||||||
settingMutex.Lock()
|
settingMutex.Lock()
|
||||||
defer settingMutex.Unlock()
|
defer settingMutex.Unlock()
|
||||||
defaultSetting = setting
|
defaultSetting = setting
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBeegoRequest return *BeegoHttpRequest with specific method
|
// NewBeegoRequest returns *BeegoHttpRequest with specific method
|
||||||
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
||||||
var resp http.Response
|
var resp http.Response
|
||||||
u, err := url.Parse(rawurl)
|
u, err := url.Parse(rawurl)
|
||||||
@ -145,9 +151,10 @@ type BeegoHTTPSettings struct {
|
|||||||
DumpBody bool
|
DumpBody bool
|
||||||
Retries int // if set to -1 means will retry forever
|
Retries int // if set to -1 means will retry forever
|
||||||
RetryDelay time.Duration
|
RetryDelay time.Duration
|
||||||
|
FilterChains []FilterChain
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
|
// BeegoHTTPRequest provides more useful methods than http.Request for requesting a url.
|
||||||
type BeegoHTTPRequest struct {
|
type BeegoHTTPRequest struct {
|
||||||
url string
|
url string
|
||||||
req *http.Request
|
req *http.Request
|
||||||
@ -159,12 +166,12 @@ type BeegoHTTPRequest struct {
|
|||||||
dump []byte
|
dump []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRequest return the request object
|
// GetRequest returns the request object
|
||||||
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
|
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
|
||||||
return b.req
|
return b.req
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting Change request settings
|
// Setting changes request settings
|
||||||
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
|
||||||
b.setting = setting
|
b.setting = setting
|
||||||
return b
|
return b
|
||||||
@ -195,26 +202,27 @@ func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retries sets Retries times.
|
// Retries sets Retries times.
|
||||||
// default is 0 means no retried.
|
// default is 0 (never retry)
|
||||||
// -1 means retried forever.
|
// -1 retry indefinitely (forever)
|
||||||
// others means retried times.
|
// Other numbers specify the exact retry amount
|
||||||
func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
|
||||||
b.setting.Retries = times
|
b.setting.Retries = times
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RetryDelay sets the time to sleep between reconnection attempts
|
||||||
func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
|
||||||
b.setting.RetryDelay = delay
|
b.setting.RetryDelay = delay
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// DumpBody setting whether need to Dump the Body.
|
// DumpBody sets the DumbBody field
|
||||||
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
|
||||||
b.setting.DumpBody = isdump
|
b.setting.DumpBody = isdump
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// DumpRequest return the DumpRequest
|
// DumpRequest returns the DumpRequest
|
||||||
func (b *BeegoHTTPRequest) DumpRequest() []byte {
|
func (b *BeegoHTTPRequest) DumpRequest() []byte {
|
||||||
return b.dump
|
return b.dump
|
||||||
}
|
}
|
||||||
@ -226,13 +234,13 @@ func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Dura
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTLSClientConfig sets tls connection configurations if visiting https url.
|
// SetTLSClientConfig sets TLS connection configuration if visiting HTTPS url.
|
||||||
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
|
||||||
b.setting.TLSClientConfig = config
|
b.setting.TLSClientConfig = config
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header add header item string in request.
|
// Header adds header item string in request.
|
||||||
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
|
||||||
b.req.Header.Set(key, value)
|
b.req.Header.Set(key, value)
|
||||||
return b
|
return b
|
||||||
@ -244,7 +252,7 @@ func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetProtocolVersion Set the protocol version for incoming requests.
|
// SetProtocolVersion sets the protocol version for incoming requests.
|
||||||
// Client requests always use HTTP/1.1.
|
// Client requests always use HTTP/1.1.
|
||||||
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
||||||
if len(vers) == 0 {
|
if len(vers) == 0 {
|
||||||
@ -261,19 +269,19 @@ func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCookie add cookie into request.
|
// SetCookie adds a cookie to the request.
|
||||||
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
|
||||||
b.req.Header.Add("Cookie", cookie.String())
|
b.req.Header.Add("Cookie", cookie.String())
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTransport set the setting transport
|
// SetTransport sets the transport field
|
||||||
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
|
||||||
b.setting.Transport = transport
|
b.setting.Transport = transport
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetProxy set the http proxy
|
// SetProxy sets the HTTP proxy
|
||||||
// example:
|
// example:
|
||||||
//
|
//
|
||||||
// func(req *http.Request) (*url.URL, error) {
|
// func(req *http.Request) (*url.URL, error) {
|
||||||
@ -294,6 +302,18 @@ func (b *BeegoHTTPRequest) SetCheckRedirect(redirect func(req *http.Request, via
|
|||||||
return b
|
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.
|
// Param adds query param in to request.
|
||||||
// params build query string as ?key1=value1&key2=value2...
|
// params build query string as ?key1=value1&key2=value2...
|
||||||
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
||||||
@ -305,14 +325,14 @@ func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostFile add a post file to the request
|
// PostFile adds a post file to the request
|
||||||
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
|
||||||
b.files[formname] = filename
|
b.files[formname] = filename
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body adds request raw body.
|
// Body adds request raw body.
|
||||||
// it supports string and []byte.
|
// Supports string and []byte.
|
||||||
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
||||||
switch t := data.(type) {
|
switch t := data.(type) {
|
||||||
case string:
|
case string:
|
||||||
@ -327,7 +347,7 @@ func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// XMLBody adds request raw body encoding by XML.
|
// XMLBody adds the request raw body encoded in XML.
|
||||||
func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||||
if b.req.Body == nil && obj != nil {
|
if b.req.Body == nil && obj != nil {
|
||||||
byts, err := xml.Marshal(obj)
|
byts, err := xml.Marshal(obj)
|
||||||
@ -341,7 +361,7 @@ func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// YAMLBody adds request raw body encoding by YAML.
|
// YAMLBody adds the request raw body encoded in YAML.
|
||||||
func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||||
if b.req.Body == nil && obj != nil {
|
if b.req.Body == nil && obj != nil {
|
||||||
byts, err := yaml.Marshal(obj)
|
byts, err := yaml.Marshal(obj)
|
||||||
@ -355,7 +375,7 @@ func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error)
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONBody adds request raw body encoding by JSON.
|
// JSONBody adds the request raw body encoded in JSON.
|
||||||
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||||
if b.req.Body == nil && obj != nil {
|
if b.req.Body == nil && obj != nil {
|
||||||
byts, err := json.Marshal(obj)
|
byts, err := json.Marshal(obj)
|
||||||
@ -437,8 +457,23 @@ func (b *BeegoHTTPRequest) getResponse() (*http.Response, error) {
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoRequest will do the client.Do
|
// DoRequest executes client.Do
|
||||||
func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
|
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
|
var paramBody string
|
||||||
if len(b.params) > 0 {
|
if len(b.params) > 0 {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
@ -530,7 +565,7 @@ func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns the body string in response.
|
// String returns the body string in response.
|
||||||
// it calls Response inner.
|
// Calls Response inner.
|
||||||
func (b *BeegoHTTPRequest) String() (string, error) {
|
func (b *BeegoHTTPRequest) String() (string, error) {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -541,7 +576,7 @@ func (b *BeegoHTTPRequest) String() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the body []byte in response.
|
// Bytes returns the body []byte in response.
|
||||||
// it calls Response inner.
|
// Calls Response inner.
|
||||||
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
||||||
if b.body != nil {
|
if b.body != nil {
|
||||||
return b.body, nil
|
return b.body, nil
|
||||||
@ -567,7 +602,7 @@ func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToFile saves the body data in response to one file.
|
// ToFile saves the body data in response to one file.
|
||||||
// it calls Response inner.
|
// Calls Response inner.
|
||||||
func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
||||||
resp, err := b.getResponse()
|
resp, err := b.getResponse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -590,7 +625,7 @@ func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check that the file directory exists, there is no automatically created
|
// Check if the file directory exists. If it doesn't then it's created
|
||||||
func pathExistAndMkdir(filename string) (err error) {
|
func pathExistAndMkdir(filename string) (err error) {
|
||||||
filename = path.Dir(filename)
|
filename = path.Dir(filename)
|
||||||
_, err = os.Stat(filename)
|
_, err = os.Stat(filename)
|
||||||
@ -607,7 +642,7 @@ func pathExistAndMkdir(filename string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToJSON returns the map that marshals from the body bytes as json in response.
|
// ToJSON returns the map that marshals from the body bytes as json in response.
|
||||||
// it calls Response inner.
|
// Calls Response inner.
|
||||||
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -617,7 +652,7 @@ func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToXML returns the map that marshals from the body bytes as xml in response .
|
// ToXML returns the map that marshals from the body bytes as xml in response .
|
||||||
// it calls Response inner.
|
// Calls Response inner.
|
||||||
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -627,7 +662,7 @@ func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToYAML returns the map that marshals from the body bytes as yaml in response .
|
// ToYAML returns the map that marshals from the body bytes as yaml in response .
|
||||||
// it calls Response inner.
|
// Calls Response inner.
|
||||||
func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
||||||
data, err := b.Bytes()
|
data, err := b.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -636,7 +671,7 @@ func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
|||||||
return yaml.Unmarshal(data, v)
|
return yaml.Unmarshal(data, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response executes request client gets response mannually.
|
// Response executes request client gets response manually.
|
||||||
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
|
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
|
||||||
return b.getResponse()
|
return b.getResponse()
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ const (
|
|||||||
jsonFormat = "JSON_FORMAT"
|
jsonFormat = "JSON_FORMAT"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccessLogRecord struct for holding access log data.
|
// AccessLogRecord is astruct for holding access log data.
|
||||||
type AccessLogRecord struct {
|
type AccessLogRecord struct {
|
||||||
RemoteAddr string `json:"remote_addr"`
|
RemoteAddr string `json:"remote_addr"`
|
||||||
RequestTime time.Time `json:"request_time"`
|
RequestTime time.Time `json:"request_time"`
|
||||||
|
@ -11,9 +11,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// CacheSize set the flush size
|
// CacheSize sets the flush size
|
||||||
CacheSize int = 64
|
CacheSize int = 64
|
||||||
// Delimiter define the topic delimiter
|
// Delimiter defines the topic delimiter
|
||||||
Delimiter string = "##"
|
Delimiter string = "##"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// aliLSWriter implements LoggerInterface.
|
// aliLSWriter implements LoggerInterface.
|
||||||
// it writes messages in keep-live tcp connection.
|
// Writes messages in keep-live tcp connection.
|
||||||
type aliLSWriter struct {
|
type aliLSWriter struct {
|
||||||
store *LogStore
|
store *LogStore
|
||||||
group []*LogGroup
|
group []*LogGroup
|
||||||
@ -41,14 +41,14 @@ type aliLSWriter struct {
|
|||||||
Config
|
Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAliLS create a new Logger
|
// NewAliLS creates a new Logger
|
||||||
func NewAliLS() logs.Logger {
|
func NewAliLS() logs.Logger {
|
||||||
alils := new(aliLSWriter)
|
alils := new(aliLSWriter)
|
||||||
alils.Level = logs.LevelTrace
|
alils.Level = logs.LevelTrace
|
||||||
return alils
|
return alils
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init parse config and init struct
|
// Init parses config and initializes struct
|
||||||
func (c *aliLSWriter) Init(jsonConfig string) (err error) {
|
func (c *aliLSWriter) Init(jsonConfig string) (err error) {
|
||||||
|
|
||||||
json.Unmarshal([]byte(jsonConfig), c)
|
json.Unmarshal([]byte(jsonConfig), c)
|
||||||
@ -101,8 +101,8 @@ func (c *aliLSWriter) Init(jsonConfig string) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in connection.
|
// WriteMsg writes a message in connection.
|
||||||
// if connection is down, try to re-connect.
|
// If connection is down, try to re-connect.
|
||||||
func (c *aliLSWriter) WriteMsg(when time.Time, msg string, level int) (err error) {
|
func (c *aliLSWriter) WriteMsg(when time.Time, msg string, level int) (err error) {
|
||||||
|
|
||||||
if level > c.Level {
|
if level > c.Level {
|
||||||
|
@ -4,10 +4,10 @@ const (
|
|||||||
version = "0.5.0" // SDK version
|
version = "0.5.0" // SDK version
|
||||||
signatureMethod = "hmac-sha1" // Signature method
|
signatureMethod = "hmac-sha1" // Signature method
|
||||||
|
|
||||||
// OffsetNewest stands for the log head offset, i.e. the offset that will be
|
// OffsetNewest is the log head offset, i.e. the offset that will be
|
||||||
// assigned to the next message that will be produced to the shard.
|
// assigned to the next message that will be produced to the shard.
|
||||||
OffsetNewest = "end"
|
OffsetNewest = "end"
|
||||||
// OffsetOldest stands for the oldest offset available on the logstore for a
|
// OffsetOldest is the the oldest offset available on the logstore for a
|
||||||
// shard.
|
// shard.
|
||||||
OffsetOldest = "begin"
|
OffsetOldest = "begin"
|
||||||
)
|
)
|
||||||
|
@ -31,13 +31,13 @@ type Log struct {
|
|||||||
// Reset the Log
|
// Reset the Log
|
||||||
func (m *Log) Reset() { *m = Log{} }
|
func (m *Log) Reset() { *m = Log{} }
|
||||||
|
|
||||||
// String return the Compact Log
|
// String returns the Compact Log
|
||||||
func (m *Log) String() string { return proto.CompactTextString(m) }
|
func (m *Log) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
// ProtoMessage not implemented
|
// ProtoMessage not implemented
|
||||||
func (*Log) ProtoMessage() {}
|
func (*Log) ProtoMessage() {}
|
||||||
|
|
||||||
// GetTime return the Log's Time
|
// GetTime returns the Log's Time
|
||||||
func (m *Log) GetTime() uint32 {
|
func (m *Log) GetTime() uint32 {
|
||||||
if m != nil && m.Time != nil {
|
if m != nil && m.Time != nil {
|
||||||
return *m.Time
|
return *m.Time
|
||||||
@ -45,7 +45,7 @@ func (m *Log) GetTime() uint32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContents return the Log's Contents
|
// GetContents returns the Log's Contents
|
||||||
func (m *Log) GetContents() []*LogContent {
|
func (m *Log) GetContents() []*LogContent {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Contents
|
return m.Contents
|
||||||
@ -53,7 +53,7 @@ func (m *Log) GetContents() []*LogContent {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogContent define the Log content struct
|
// LogContent defines the Log content struct
|
||||||
type LogContent struct {
|
type LogContent struct {
|
||||||
Key *string `protobuf:"bytes,1,req,name=Key" json:"Key,omitempty"`
|
Key *string `protobuf:"bytes,1,req,name=Key" json:"Key,omitempty"`
|
||||||
Value *string `protobuf:"bytes,2,req,name=Value" json:"Value,omitempty"`
|
Value *string `protobuf:"bytes,2,req,name=Value" json:"Value,omitempty"`
|
||||||
@ -63,13 +63,13 @@ type LogContent struct {
|
|||||||
// Reset LogContent
|
// Reset LogContent
|
||||||
func (m *LogContent) Reset() { *m = LogContent{} }
|
func (m *LogContent) Reset() { *m = LogContent{} }
|
||||||
|
|
||||||
// String return the compact text
|
// String returns the compact text
|
||||||
func (m *LogContent) String() string { return proto.CompactTextString(m) }
|
func (m *LogContent) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
// ProtoMessage not implemented
|
// ProtoMessage not implemented
|
||||||
func (*LogContent) ProtoMessage() {}
|
func (*LogContent) ProtoMessage() {}
|
||||||
|
|
||||||
// GetKey return the Key
|
// GetKey returns the key
|
||||||
func (m *LogContent) GetKey() string {
|
func (m *LogContent) GetKey() string {
|
||||||
if m != nil && m.Key != nil {
|
if m != nil && m.Key != nil {
|
||||||
return *m.Key
|
return *m.Key
|
||||||
@ -77,7 +77,7 @@ func (m *LogContent) GetKey() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetValue return the Value
|
// GetValue returns the value
|
||||||
func (m *LogContent) GetValue() string {
|
func (m *LogContent) GetValue() string {
|
||||||
if m != nil && m.Value != nil {
|
if m != nil && m.Value != nil {
|
||||||
return *m.Value
|
return *m.Value
|
||||||
@ -85,7 +85,7 @@ func (m *LogContent) GetValue() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogGroup define the logs struct
|
// LogGroup defines the logs struct
|
||||||
type LogGroup struct {
|
type LogGroup struct {
|
||||||
Logs []*Log `protobuf:"bytes,1,rep,name=Logs" json:"Logs,omitempty"`
|
Logs []*Log `protobuf:"bytes,1,rep,name=Logs" json:"Logs,omitempty"`
|
||||||
Reserved *string `protobuf:"bytes,2,opt,name=Reserved" json:"Reserved,omitempty"`
|
Reserved *string `protobuf:"bytes,2,opt,name=Reserved" json:"Reserved,omitempty"`
|
||||||
@ -97,13 +97,13 @@ type LogGroup struct {
|
|||||||
// Reset LogGroup
|
// Reset LogGroup
|
||||||
func (m *LogGroup) Reset() { *m = LogGroup{} }
|
func (m *LogGroup) Reset() { *m = LogGroup{} }
|
||||||
|
|
||||||
// String return the compact text
|
// String returns the compact text
|
||||||
func (m *LogGroup) String() string { return proto.CompactTextString(m) }
|
func (m *LogGroup) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
// ProtoMessage not implemented
|
// ProtoMessage not implemented
|
||||||
func (*LogGroup) ProtoMessage() {}
|
func (*LogGroup) ProtoMessage() {}
|
||||||
|
|
||||||
// GetLogs return the loggroup logs
|
// GetLogs returns the loggroup logs
|
||||||
func (m *LogGroup) GetLogs() []*Log {
|
func (m *LogGroup) GetLogs() []*Log {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Logs
|
return m.Logs
|
||||||
@ -111,7 +111,8 @@ func (m *LogGroup) GetLogs() []*Log {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReserved return Reserved
|
// GetReserved returns Reserved. An empty string is returned
|
||||||
|
// if an error occurs
|
||||||
func (m *LogGroup) GetReserved() string {
|
func (m *LogGroup) GetReserved() string {
|
||||||
if m != nil && m.Reserved != nil {
|
if m != nil && m.Reserved != nil {
|
||||||
return *m.Reserved
|
return *m.Reserved
|
||||||
@ -119,7 +120,8 @@ func (m *LogGroup) GetReserved() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTopic return Topic
|
// GetTopic returns Topic. An empty string is returned
|
||||||
|
// if an error occurs
|
||||||
func (m *LogGroup) GetTopic() string {
|
func (m *LogGroup) GetTopic() string {
|
||||||
if m != nil && m.Topic != nil {
|
if m != nil && m.Topic != nil {
|
||||||
return *m.Topic
|
return *m.Topic
|
||||||
@ -127,7 +129,8 @@ func (m *LogGroup) GetTopic() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSource return Source
|
// GetSource returns source. An empty string is returned
|
||||||
|
// if an error occurs
|
||||||
func (m *LogGroup) GetSource() string {
|
func (m *LogGroup) GetSource() string {
|
||||||
if m != nil && m.Source != nil {
|
if m != nil && m.Source != nil {
|
||||||
return *m.Source
|
return *m.Source
|
||||||
@ -135,7 +138,7 @@ func (m *LogGroup) GetSource() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogGroupList define the LogGroups
|
// LogGroupList defines the LogGroups
|
||||||
type LogGroupList struct {
|
type LogGroupList struct {
|
||||||
LogGroups []*LogGroup `protobuf:"bytes,1,rep,name=logGroups" json:"logGroups,omitempty"`
|
LogGroups []*LogGroup `protobuf:"bytes,1,rep,name=logGroups" json:"logGroups,omitempty"`
|
||||||
XXXUnrecognized []byte `json:"-"`
|
XXXUnrecognized []byte `json:"-"`
|
||||||
@ -144,13 +147,13 @@ type LogGroupList struct {
|
|||||||
// Reset LogGroupList
|
// Reset LogGroupList
|
||||||
func (m *LogGroupList) Reset() { *m = LogGroupList{} }
|
func (m *LogGroupList) Reset() { *m = LogGroupList{} }
|
||||||
|
|
||||||
// String return compact text
|
// String returns compact text
|
||||||
func (m *LogGroupList) String() string { return proto.CompactTextString(m) }
|
func (m *LogGroupList) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
// ProtoMessage not implemented
|
// ProtoMessage not implemented
|
||||||
func (*LogGroupList) ProtoMessage() {}
|
func (*LogGroupList) ProtoMessage() {}
|
||||||
|
|
||||||
// GetLogGroups return the LogGroups
|
// GetLogGroups returns the LogGroups
|
||||||
func (m *LogGroupList) GetLogGroups() []*LogGroup {
|
func (m *LogGroupList) GetLogGroups() []*LogGroup {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.LogGroups
|
return m.LogGroups
|
||||||
@ -158,7 +161,7 @@ func (m *LogGroupList) GetLogGroups() []*LogGroup {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal the logs to byte slice
|
// Marshal marshals the logs to byte slice
|
||||||
func (m *Log) Marshal() (data []byte, err error) {
|
func (m *Log) Marshal() (data []byte, err error) {
|
||||||
size := m.Size()
|
size := m.Size()
|
||||||
data = make([]byte, size)
|
data = make([]byte, size)
|
||||||
@ -353,7 +356,7 @@ func encodeVarintLog(data []byte, offset int, v uint64) int {
|
|||||||
return offset + 1
|
return offset + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size return the log's size
|
// Size returns the log's size
|
||||||
func (m *Log) Size() (n int) {
|
func (m *Log) Size() (n int) {
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
@ -372,7 +375,7 @@ func (m *Log) Size() (n int) {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size return LogContent size based on Key and Value
|
// Size returns LogContent size based on Key and Value
|
||||||
func (m *LogContent) Size() (n int) {
|
func (m *LogContent) Size() (n int) {
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
@ -390,7 +393,7 @@ func (m *LogContent) Size() (n int) {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size return LogGroup size based on Logs
|
// Size returns LogGroup size based on Logs
|
||||||
func (m *LogGroup) Size() (n int) {
|
func (m *LogGroup) Size() (n int) {
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
@ -418,7 +421,7 @@ func (m *LogGroup) Size() (n int) {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size return LogGroupList size
|
// Size returns LogGroupList size
|
||||||
func (m *LogGroupList) Size() (n int) {
|
func (m *LogGroupList) Size() (n int) {
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
@ -448,7 +451,7 @@ func sozLog(x uint64) (n int) {
|
|||||||
return sovLog((x << 1) ^ (x >> 63))
|
return sovLog((x << 1) ^ (x >> 63))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal data to log
|
// Unmarshal unmarshals data to log
|
||||||
func (m *Log) Unmarshal(data []byte) error {
|
func (m *Log) Unmarshal(data []byte) error {
|
||||||
var hasFields [1]uint64
|
var hasFields [1]uint64
|
||||||
l := len(data)
|
l := len(data)
|
||||||
@ -557,7 +560,7 @@ func (m *Log) Unmarshal(data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal data to LogContent
|
// Unmarshal unmarshals data to LogContent
|
||||||
func (m *LogContent) Unmarshal(data []byte) error {
|
func (m *LogContent) Unmarshal(data []byte) error {
|
||||||
var hasFields [1]uint64
|
var hasFields [1]uint64
|
||||||
l := len(data)
|
l := len(data)
|
||||||
@ -679,7 +682,7 @@ func (m *LogContent) Unmarshal(data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal data to LogGroup
|
// Unmarshal unmarshals data to LogGroup
|
||||||
func (m *LogGroup) Unmarshal(data []byte) error {
|
func (m *LogGroup) Unmarshal(data []byte) error {
|
||||||
l := len(data)
|
l := len(data)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
@ -853,7 +856,7 @@ func (m *LogGroup) Unmarshal(data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal data to LogGroupList
|
// Unmarshal unmarshals data to LogGroupList
|
||||||
func (m *LogGroupList) Unmarshal(data []byte) error {
|
func (m *LogGroupList) Unmarshal(data []byte) error {
|
||||||
l := len(data)
|
l := len(data)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package alils
|
package alils
|
||||||
|
|
||||||
// InputDetail define log detail
|
// InputDetail defines log detail
|
||||||
type InputDetail struct {
|
type InputDetail struct {
|
||||||
LogType string `json:"logType"`
|
LogType string `json:"logType"`
|
||||||
LogPath string `json:"logPath"`
|
LogPath string `json:"logPath"`
|
||||||
@ -15,13 +15,13 @@ type InputDetail struct {
|
|||||||
TopicFormat string `json:"topicFormat"`
|
TopicFormat string `json:"topicFormat"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OutputDetail define the output detail
|
// OutputDetail defines the output detail
|
||||||
type OutputDetail struct {
|
type OutputDetail struct {
|
||||||
Endpoint string `json:"endpoint"`
|
Endpoint string `json:"endpoint"`
|
||||||
LogStoreName string `json:"logstoreName"`
|
LogStoreName string `json:"logstoreName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogConfig define Log Config
|
// LogConfig defines Log Config
|
||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
Name string `json:"configName"`
|
Name string `json:"configName"`
|
||||||
InputType string `json:"inputType"`
|
InputType string `json:"inputType"`
|
||||||
|
@ -20,7 +20,7 @@ type errorMessage struct {
|
|||||||
Message string `json:"errorMessage"`
|
Message string `json:"errorMessage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogProject Define the Ali Project detail
|
// LogProject defines the Ali Project detail
|
||||||
type LogProject struct {
|
type LogProject struct {
|
||||||
Name string // Project name
|
Name string // Project name
|
||||||
Endpoint string // IP or hostname of SLS endpoint
|
Endpoint string // IP or hostname of SLS endpoint
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LogStore Store the logs
|
// LogStore stores the logs
|
||||||
type LogStore struct {
|
type LogStore struct {
|
||||||
Name string `json:"logstoreName"`
|
Name string `json:"logstoreName"`
|
||||||
TTL int
|
TTL int
|
||||||
@ -24,7 +24,7 @@ type LogStore struct {
|
|||||||
project *LogProject
|
project *LogProject
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shard define the Log Shard
|
// Shard defines the Log Shard
|
||||||
type Shard struct {
|
type Shard struct {
|
||||||
ShardID int `json:"shardID"`
|
ShardID int `json:"shardID"`
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ func (s *LogStore) ListShards() (shardIDs []int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutLogs put logs into logstore.
|
// PutLogs puts logs into logstore.
|
||||||
// The callers should transform user logs into LogGroup.
|
// The callers should transform user logs into LogGroup.
|
||||||
func (s *LogStore) PutLogs(lg *LogGroup) (err error) {
|
func (s *LogStore) PutLogs(lg *LogGroup) (err error) {
|
||||||
body, err := proto.Marshal(lg)
|
body, err := proto.Marshal(lg)
|
||||||
|
@ -8,13 +8,13 @@ import (
|
|||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MachineGroupAttribute define the Attribute
|
// MachineGroupAttribute defines the Attribute
|
||||||
type MachineGroupAttribute struct {
|
type MachineGroupAttribute struct {
|
||||||
ExternalName string `json:"externalName"`
|
ExternalName string `json:"externalName"`
|
||||||
TopicName string `json:"groupTopic"`
|
TopicName string `json:"groupTopic"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MachineGroup define the machine Group
|
// MachineGroup defines the machine Group
|
||||||
type MachineGroup struct {
|
type MachineGroup struct {
|
||||||
Name string `json:"groupName"`
|
Name string `json:"groupName"`
|
||||||
Type string `json:"groupType"`
|
Type string `json:"groupType"`
|
||||||
@ -29,20 +29,20 @@ type MachineGroup struct {
|
|||||||
project *LogProject
|
project *LogProject
|
||||||
}
|
}
|
||||||
|
|
||||||
// Machine define the Machine
|
// Machine defines the Machine
|
||||||
type Machine struct {
|
type Machine struct {
|
||||||
IP string
|
IP string
|
||||||
UniqueID string `json:"machine-uniqueid"`
|
UniqueID string `json:"machine-uniqueid"`
|
||||||
UserdefinedID string `json:"userdefined-id"`
|
UserdefinedID string `json:"userdefined-id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MachineList define the Machine List
|
// MachineList defines the Machine List
|
||||||
type MachineList struct {
|
type MachineList struct {
|
||||||
Total int
|
Total int
|
||||||
Machines []*Machine
|
Machines []*Machine
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListMachines returns machine list of this machine group.
|
// ListMachines returns the machine list of this machine group.
|
||||||
func (m *MachineGroup) ListMachines() (ms []*Machine, total int, err error) {
|
func (m *MachineGroup) ListMachines() (ms []*Machine, total int, err error) {
|
||||||
h := map[string]string{
|
h := map[string]string{
|
||||||
"x-sls-bodyrawsize": "0",
|
"x-sls-bodyrawsize": "0",
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// connWriter implements LoggerInterface.
|
// connWriter implements LoggerInterface.
|
||||||
// it writes messages in keep-live tcp connection.
|
// Writes messages in keep-live tcp connection.
|
||||||
type connWriter struct {
|
type connWriter struct {
|
||||||
lg *logWriter
|
lg *logWriter
|
||||||
innerWriter io.WriteCloser
|
innerWriter io.WriteCloser
|
||||||
@ -33,21 +33,21 @@ type connWriter struct {
|
|||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConn create new ConnWrite returning as LoggerInterface.
|
// NewConn creates new ConnWrite returning as LoggerInterface.
|
||||||
func NewConn() Logger {
|
func NewConn() Logger {
|
||||||
conn := new(connWriter)
|
conn := new(connWriter)
|
||||||
conn.Level = LevelTrace
|
conn.Level = LevelTrace
|
||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init init connection writer with json config.
|
// Init initializes a connection writer with json config.
|
||||||
// json config only need key "level".
|
// json config only needs they "level" key
|
||||||
func (c *connWriter) Init(jsonConfig string) error {
|
func (c *connWriter) Init(jsonConfig string) error {
|
||||||
return json.Unmarshal([]byte(jsonConfig), c)
|
return json.Unmarshal([]byte(jsonConfig), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in connection.
|
// WriteMsg writes message in connection.
|
||||||
// if connection is down, try to re-connect.
|
// If connection is down, try to re-connect.
|
||||||
func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
|
func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > c.Level {
|
if level > c.Level {
|
||||||
return nil
|
return nil
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
// brush is a color join function
|
// brush is a color join function
|
||||||
type brush func(string) string
|
type brush func(string) string
|
||||||
|
|
||||||
// newBrush return a fix color Brush
|
// newBrush returns a fix color Brush
|
||||||
func newBrush(color string) brush {
|
func newBrush(color string) brush {
|
||||||
pre := "\033["
|
pre := "\033["
|
||||||
reset := "\033[0m"
|
reset := "\033[0m"
|
||||||
@ -53,7 +53,7 @@ type consoleWriter struct {
|
|||||||
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConsole create ConsoleWriter returning as LoggerInterface.
|
// NewConsole creates ConsoleWriter returning as LoggerInterface.
|
||||||
func NewConsole() Logger {
|
func NewConsole() Logger {
|
||||||
cw := &consoleWriter{
|
cw := &consoleWriter{
|
||||||
lg: newLogWriter(ansicolor.NewAnsiColorWriter(os.Stdout)),
|
lg: newLogWriter(ansicolor.NewAnsiColorWriter(os.Stdout)),
|
||||||
@ -63,8 +63,8 @@ func NewConsole() Logger {
|
|||||||
return cw
|
return cw
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init init console logger.
|
// Init initianlizes the console logger.
|
||||||
// jsonConfig like '{"level":LevelTrace}'.
|
// jsonConfig must be in the format '{"level":LevelTrace}'
|
||||||
func (c *consoleWriter) Init(jsonConfig string) error {
|
func (c *consoleWriter) Init(jsonConfig string) error {
|
||||||
if len(jsonConfig) == 0 {
|
if len(jsonConfig) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -72,7 +72,7 @@ func (c *consoleWriter) Init(jsonConfig string) error {
|
|||||||
return json.Unmarshal([]byte(jsonConfig), c)
|
return json.Unmarshal([]byte(jsonConfig), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in console.
|
// WriteMsg writes message in console.
|
||||||
func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
|
func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > c.Level {
|
if level > c.Level {
|
||||||
return nil
|
return nil
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/astaxie/beego/pkg/logs"
|
"github.com/astaxie/beego/pkg/logs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewES return a LoggerInterface
|
// NewES returns a LoggerInterface
|
||||||
func NewES() logs.Logger {
|
func NewES() logs.Logger {
|
||||||
cw := &esLogger{
|
cw := &esLogger{
|
||||||
Level: logs.LevelDebug,
|
Level: logs.LevelDebug,
|
||||||
@ -59,7 +59,7 @@ func (el *esLogger) Init(jsonconfig string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg will write the msg and level into es
|
// WriteMsg writes the msg and level into es
|
||||||
func (el *esLogger) WriteMsg(when time.Time, msg string, level int) error {
|
func (el *esLogger) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > el.Level {
|
if level > el.Level {
|
||||||
return nil
|
return nil
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// fileLogWriter implements LoggerInterface.
|
// fileLogWriter implements LoggerInterface.
|
||||||
// It writes messages by lines limit, file size limit, or time frequency.
|
// Writes messages by lines limit, file size limit, or time frequency.
|
||||||
type fileLogWriter struct {
|
type fileLogWriter struct {
|
||||||
sync.RWMutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize
|
sync.RWMutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize
|
||||||
// The opened file
|
// The opened file
|
||||||
@ -71,7 +71,7 @@ type fileLogWriter struct {
|
|||||||
fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix
|
fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFileWriter create a FileLogWriter returning as LoggerInterface.
|
// newFileWriter creates a FileLogWriter returning as LoggerInterface.
|
||||||
func newFileWriter() Logger {
|
func newFileWriter() Logger {
|
||||||
w := &fileLogWriter{
|
w := &fileLogWriter{
|
||||||
Daily: true,
|
Daily: true,
|
||||||
@ -143,7 +143,7 @@ func (w *fileLogWriter) needRotateHourly(size int, hour int) bool {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write logger message into file.
|
// WriteMsg writes logger message into file.
|
||||||
func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
|
func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > w.Level {
|
if level > w.Level {
|
||||||
return nil
|
return nil
|
||||||
@ -286,7 +286,7 @@ func (w *fileLogWriter) lines() (int, error) {
|
|||||||
return count, nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoRotate means it need to write file in new file.
|
// DoRotate means it needs to write logs into a new file.
|
||||||
// new file name like xx.2013-01-01.log (daily) or xx.001.log (by line or size)
|
// 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 {
|
func (w *fileLogWriter) doRotate(logTime time.Time) error {
|
||||||
// file exists
|
// file exists
|
||||||
@ -397,7 +397,7 @@ func (w *fileLogWriter) Destroy() {
|
|||||||
w.fileWriter.Close()
|
w.fileWriter.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush flush file logger.
|
// Flush flushes file logger.
|
||||||
// there are no buffering messages in file logger in memory.
|
// there are no buffering messages in file logger in memory.
|
||||||
// flush file means sync file from disk.
|
// flush file means sync file from disk.
|
||||||
func (w *fileLogWriter) Flush() {
|
func (w *fileLogWriter) Flush() {
|
||||||
|
@ -18,7 +18,7 @@ type JLWriter struct {
|
|||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// newJLWriter create jiaoliao writer.
|
// newJLWriter creates jiaoliao writer.
|
||||||
func newJLWriter() Logger {
|
func newJLWriter() Logger {
|
||||||
return &JLWriter{Level: LevelTrace}
|
return &JLWriter{Level: LevelTrace}
|
||||||
}
|
}
|
||||||
@ -28,8 +28,8 @@ func (s *JLWriter) Init(jsonconfig string) error {
|
|||||||
return json.Unmarshal([]byte(jsonconfig), s)
|
return json.Unmarshal([]byte(jsonconfig), s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in smtp writer.
|
// WriteMsg writes message in smtp writer.
|
||||||
// it will send an email with subject and only this message.
|
// Sends an email with subject and only this message.
|
||||||
func (s *JLWriter) WriteMsg(when time.Time, msg string, level int) error {
|
func (s *JLWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > s.Level {
|
if level > s.Level {
|
||||||
return nil
|
return nil
|
||||||
|
@ -108,7 +108,7 @@ func Register(name string, log newLoggerFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BeeLogger is default logger in beego application.
|
// BeeLogger is default logger in beego application.
|
||||||
// it can contain several providers and log message into all providers.
|
// Can contain several providers and log message into all providers.
|
||||||
type BeeLogger struct {
|
type BeeLogger struct {
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
level int
|
level int
|
||||||
@ -140,7 +140,7 @@ type logMsg struct {
|
|||||||
var logMsgPool *sync.Pool
|
var logMsgPool *sync.Pool
|
||||||
|
|
||||||
// NewLogger returns a new BeeLogger.
|
// NewLogger returns a new BeeLogger.
|
||||||
// channelLen means the number of messages in chan(used where asynchronous is true).
|
// channelLen: 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.
|
// if the buffering chan is full, logger adapters write to file or other way.
|
||||||
func NewLogger(channelLens ...int64) *BeeLogger {
|
func NewLogger(channelLens ...int64) *BeeLogger {
|
||||||
bl := new(BeeLogger)
|
bl := new(BeeLogger)
|
||||||
@ -155,7 +155,7 @@ func NewLogger(channelLens ...int64) *BeeLogger {
|
|||||||
return bl
|
return bl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Async set the log to asynchronous and start the goroutine
|
// Async sets the log to asynchronous and start the goroutine
|
||||||
func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
|
func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
|
||||||
bl.lock.Lock()
|
bl.lock.Lock()
|
||||||
defer bl.lock.Unlock()
|
defer bl.lock.Unlock()
|
||||||
@ -178,7 +178,7 @@ func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetLogger provides a given logger adapter into BeeLogger with config string.
|
// SetLogger provides a given logger adapter into BeeLogger with config string.
|
||||||
// config need to be correct JSON as string: {"interval":360}.
|
// config must in in JSON format like {"interval":360}}
|
||||||
func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
|
func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
|
||||||
config := append(configs, "{}")[0]
|
config := append(configs, "{}")[0]
|
||||||
for _, l := range bl.outputs {
|
for _, l := range bl.outputs {
|
||||||
@ -203,7 +203,7 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetLogger provides a given logger adapter into BeeLogger with config string.
|
// SetLogger provides a given logger adapter into BeeLogger with config string.
|
||||||
// config need to be correct JSON as string: {"interval":360}.
|
// config must in in JSON format like {"interval":360}}
|
||||||
func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
|
func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
|
||||||
bl.lock.Lock()
|
bl.lock.Lock()
|
||||||
defer bl.lock.Unlock()
|
defer bl.lock.Unlock()
|
||||||
@ -214,7 +214,7 @@ func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
|
|||||||
return bl.setLogger(adapterName, configs...)
|
return bl.setLogger(adapterName, configs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DelLogger remove a logger adapter in BeeLogger.
|
// DelLogger removes a logger adapter in BeeLogger.
|
||||||
func (bl *BeeLogger) DelLogger(adapterName string) error {
|
func (bl *BeeLogger) DelLogger(adapterName string) error {
|
||||||
bl.lock.Lock()
|
bl.lock.Lock()
|
||||||
defer bl.lock.Unlock()
|
defer bl.lock.Unlock()
|
||||||
@ -306,9 +306,9 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLevel Set log message level.
|
// SetLevel sets log message level.
|
||||||
// If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
|
// If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
|
||||||
// log providers will not even be sent the message.
|
// log providers will not be sent the message.
|
||||||
func (bl *BeeLogger) SetLevel(l int) {
|
func (bl *BeeLogger) SetLevel(l int) {
|
||||||
bl.level = l
|
bl.level = l
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ type SLACKWriter struct {
|
|||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSLACKWriter create jiaoliao writer.
|
// newSLACKWriter creates jiaoliao writer.
|
||||||
func newSLACKWriter() Logger {
|
func newSLACKWriter() Logger {
|
||||||
return &SLACKWriter{Level: LevelTrace}
|
return &SLACKWriter{Level: LevelTrace}
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ func (s *SLACKWriter) Init(jsonconfig string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in smtp writer.
|
// WriteMsg write message in smtp writer.
|
||||||
// it will send an email with subject and only this message.
|
// Sends an email with subject and only this message.
|
||||||
func (s *SLACKWriter) WriteMsg(when time.Time, msg string, level int) error {
|
func (s *SLACKWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > s.Level {
|
if level > s.Level {
|
||||||
return nil
|
return nil
|
||||||
|
@ -35,7 +35,7 @@ type SMTPWriter struct {
|
|||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSMTPWriter create smtp writer.
|
// NewSMTPWriter creates the smtp writer.
|
||||||
func newSMTPWriter() Logger {
|
func newSMTPWriter() Logger {
|
||||||
return &SMTPWriter{Level: LevelTrace}
|
return &SMTPWriter{Level: LevelTrace}
|
||||||
}
|
}
|
||||||
@ -115,8 +115,8 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd
|
|||||||
return client.Quit()
|
return client.Quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in smtp writer.
|
// WriteMsg writes message in smtp writer.
|
||||||
// it will send an email with subject and only this message.
|
// Sends an email with subject and only this message.
|
||||||
func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
|
func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > s.Level {
|
if level > s.Level {
|
||||||
return nil
|
return nil
|
||||||
|
134
pkg/orm/do_nothing_omr_test.go
Normal file
134
pkg/orm/do_nothing_omr_test.go
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDoNothingOrm(t *testing.T) {
|
||||||
|
o := &DoNothingOrm{}
|
||||||
|
err := o.DoTxWithCtxAndOpts(nil, nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
err = o.DoTxWithCtx(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
err = o.DoTx(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
err = o.DoTxWithOpts(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assert.Nil(t, o.Driver())
|
||||||
|
|
||||||
|
assert.Nil(t, o.QueryM2MWithCtx(nil, nil, ""))
|
||||||
|
assert.Nil(t, o.QueryM2M(nil, ""))
|
||||||
|
assert.Nil(t, o.ReadWithCtx(nil, nil))
|
||||||
|
assert.Nil(t, o.Read(nil))
|
||||||
|
|
||||||
|
txOrm, err := o.BeginWithCtxAndOpts(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Nil(t, txOrm)
|
||||||
|
|
||||||
|
txOrm, err = o.BeginWithCtx(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Nil(t, txOrm)
|
||||||
|
|
||||||
|
txOrm, err = o.BeginWithOpts(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Nil(t, txOrm)
|
||||||
|
|
||||||
|
txOrm, err = o.Begin()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Nil(t, txOrm)
|
||||||
|
|
||||||
|
assert.Nil(t, o.RawWithCtx(nil, ""))
|
||||||
|
assert.Nil(t, o.Raw(""))
|
||||||
|
|
||||||
|
i, err := o.InsertMulti(0, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.Insert(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.InsertWithCtx(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.InsertOrUpdateWithCtx(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.InsertOrUpdate(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.InsertMultiWithCtx(nil, 0, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.LoadRelatedWithCtx(nil, nil, "")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.LoadRelated(nil, "")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
assert.Nil(t, o.QueryTableWithCtx(nil, nil))
|
||||||
|
assert.Nil(t, o.QueryTable(nil))
|
||||||
|
|
||||||
|
assert.Nil(t, o.Read(nil))
|
||||||
|
assert.Nil(t, o.ReadWithCtx(nil, nil))
|
||||||
|
assert.Nil(t, o.ReadForUpdateWithCtx(nil, nil))
|
||||||
|
assert.Nil(t, o.ReadForUpdate(nil))
|
||||||
|
|
||||||
|
ok, i, err := o.ReadOrCreate(nil, "")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
assert.False(t, ok)
|
||||||
|
|
||||||
|
ok, i, err = o.ReadOrCreateWithCtx(nil, nil, "")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
assert.False(t, ok)
|
||||||
|
|
||||||
|
i, err = o.Delete(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.DeleteWithCtx(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.Update(nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
i, err = o.UpdateWithCtx(nil, nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), i)
|
||||||
|
|
||||||
|
assert.Nil(t, o.DBStats())
|
||||||
|
|
||||||
|
to := &DoNothingTxOrm{}
|
||||||
|
assert.Nil(t, to.Commit())
|
||||||
|
assert.Nil(t, to.Rollback())
|
||||||
|
}
|
178
pkg/orm/do_nothing_orm.go
Normal file
178
pkg/orm/do_nothing_orm.go
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DoNothingOrm won't do anything, usually you use this to custom your mock Ormer implementation
|
||||||
|
// I think golang mocking interface is hard to use
|
||||||
|
// this may help you to integrate with Ormer
|
||||||
|
|
||||||
|
var _ Ormer = new(DoNothingOrm)
|
||||||
|
|
||||||
|
type DoNothingOrm struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Read(md interface{}, cols ...string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) ReadForUpdate(md interface{}, cols ...string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||||
|
return false, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||||
|
return false, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...interface{}) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) QueryM2M(md interface{}, name string) QueryM2Mer {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) QueryTable(ptrStructOrTableName interface{}) QuerySeter {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) DBStats() *sql.DBStats {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Insert(md interface{}) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) InsertMulti(bulk int, mds interface{}) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Update(md interface{}, cols ...string) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Delete(md interface{}, cols ...string) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Raw(query string, args ...interface{}) RawSeter {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Driver() Driver {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) Begin() (TxOrmer, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) DoTx(task func(txOrm TxOrmer) error) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoNothingTxOrm is similar with DoNothingOrm, usually you use it to test
|
||||||
|
type DoNothingTxOrm struct {
|
||||||
|
DoNothingOrm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingTxOrm) Commit() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DoNothingTxOrm) Rollback() error {
|
||||||
|
return nil
|
||||||
|
}
|
36
pkg/orm/filter.go
Normal file
36
pkg/orm/filter.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterChain is used to build a Filter
|
||||||
|
// don't forget to call next(...) inside your Filter
|
||||||
|
type FilterChain func(next Filter) Filter
|
||||||
|
|
||||||
|
// Filter's behavior is a little big strang.
|
||||||
|
// it's only be called when users call methods of Ormer
|
||||||
|
type Filter func(ctx context.Context, inv *Invocation)
|
||||||
|
|
||||||
|
var globalFilterChains = make([]FilterChain, 0, 4)
|
||||||
|
|
||||||
|
// AddGlobalFilterChain adds a new FilterChain
|
||||||
|
// All orm instances built after this invocation will use this filterChain,
|
||||||
|
// but instances built before this invocation will not be affected
|
||||||
|
func AddGlobalFilterChain(filterChain FilterChain) {
|
||||||
|
globalFilterChains = append(globalFilterChains, filterChain)
|
||||||
|
}
|
59
pkg/orm/filter/opentracing/filter.go
Normal file
59
pkg/orm/filter/opentracing/filter.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// 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/opentracing/opentracing-go"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterChainBuilder provides an extension point
|
||||||
|
// this Filter's behavior looks a little bit strange
|
||||||
|
// for example:
|
||||||
|
// if we want to trace QuerySetter
|
||||||
|
// actually we trace invoking "QueryTable" and "QueryTableWithCtx"
|
||||||
|
type FilterChainBuilder struct {
|
||||||
|
// CustomSpanFunc users are able to custom their span
|
||||||
|
CustomSpanFunc func(span opentracing.Span, ctx context.Context, inv *orm.Invocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
|
||||||
|
return func(ctx context.Context, inv *orm.Invocation) {
|
||||||
|
operationName := builder.operationName(ctx, inv)
|
||||||
|
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
next(spanCtx, inv)
|
||||||
|
span.SetTag("Method", inv.Method)
|
||||||
|
span.SetTag("Table", inv.GetTableName())
|
||||||
|
span.SetTag("InsideTx", inv.InsideTx)
|
||||||
|
span.SetTag("TxName", spanCtx.Value(orm.TxNameKey))
|
||||||
|
|
||||||
|
if builder.CustomSpanFunc != nil {
|
||||||
|
builder.CustomSpanFunc(span, spanCtx, inv)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) operationName(ctx context.Context, inv *orm.Invocation) string {
|
||||||
|
if n, ok := ctx.Value(orm.TxNameKey).(string); ok {
|
||||||
|
return inv.Method + "#" + n
|
||||||
|
}
|
||||||
|
return inv.Method + "#" + inv.GetTableName()
|
||||||
|
}
|
43
pkg/orm/filter/opentracing/filter_test.go
Normal file
43
pkg/orm/filter/opentracing/filter_test.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// 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"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/opentracing/opentracing-go"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||||
|
next := func(ctx context.Context, inv *orm.Invocation) {
|
||||||
|
inv.TxName = "Hello"
|
||||||
|
}
|
||||||
|
|
||||||
|
builder := &FilterChainBuilder{
|
||||||
|
CustomSpanFunc: func(span opentracing.Span, ctx context.Context, inv *orm.Invocation) {
|
||||||
|
span.SetTag("hello", "hell")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
inv := &orm.Invocation{
|
||||||
|
Method: "Hello",
|
||||||
|
TxStartTime: time.Now(),
|
||||||
|
}
|
||||||
|
builder.FilterChain(next)(context.Background(), inv)
|
||||||
|
}
|
88
pkg/orm/filter/prometheus/filter.go
Normal file
88
pkg/orm/filter/prometheus/filter.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
beego "github.com/astaxie/beego/pkg"
|
||||||
|
"github.com/astaxie/beego/pkg/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterChainBuilder is an extension point,
|
||||||
|
// when we want to support some configuration,
|
||||||
|
// please use this structure
|
||||||
|
// this Filter's behavior looks a little bit strange
|
||||||
|
// for example:
|
||||||
|
// if we want to records the metrics of QuerySetter
|
||||||
|
// actually we only records metrics of invoking "QueryTable" and "QueryTableWithCtx"
|
||||||
|
type FilterChainBuilder struct {
|
||||||
|
summaryVec prometheus.ObserverVec
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFilterChainBuilder() *FilterChainBuilder {
|
||||||
|
summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||||
|
Name: "beego",
|
||||||
|
Subsystem: "orm_operation",
|
||||||
|
ConstLabels: map[string]string{
|
||||||
|
"server": beego.BConfig.ServerName,
|
||||||
|
"env": beego.BConfig.RunMode,
|
||||||
|
"appname": beego.BConfig.AppName,
|
||||||
|
},
|
||||||
|
Help: "The statics info for orm operation",
|
||||||
|
}, []string{"method", "name", "duration", "insideTx", "txName"})
|
||||||
|
|
||||||
|
prometheus.MustRegister(summaryVec)
|
||||||
|
return &FilterChainBuilder{
|
||||||
|
summaryVec: summaryVec,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
|
||||||
|
return func(ctx context.Context, inv *orm.Invocation) {
|
||||||
|
startTime := time.Now()
|
||||||
|
next(ctx, inv)
|
||||||
|
endTime := time.Now()
|
||||||
|
dur := (endTime.Sub(startTime)) / time.Millisecond
|
||||||
|
|
||||||
|
// if the TPS is too large, here may be some problem
|
||||||
|
// thinking about using goroutine pool
|
||||||
|
go builder.report(ctx, inv, dur)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) report(ctx context.Context, inv *orm.Invocation, dur time.Duration) {
|
||||||
|
// start a transaction, we don't record it
|
||||||
|
if strings.HasPrefix(inv.Method, "Begin") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if inv.Method == "Commit" || inv.Method == "Rollback" {
|
||||||
|
builder.reportTxn(ctx, inv)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
builder.summaryVec.WithLabelValues(inv.Method, inv.GetTableName(), strconv.Itoa(int(dur)),
|
||||||
|
strconv.FormatBool(inv.InsideTx), inv.TxName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) reportTxn(ctx context.Context, inv *orm.Invocation) {
|
||||||
|
dur := time.Now().Sub(inv.TxStartTime) / time.Millisecond
|
||||||
|
builder.summaryVec.WithLabelValues(inv.Method, inv.TxName, strconv.Itoa(int(dur)),
|
||||||
|
strconv.FormatBool(inv.InsideTx), inv.TxName)
|
||||||
|
}
|
60
pkg/orm/filter/prometheus/filter_test.go
Normal file
60
pkg/orm/filter/prometheus/filter_test.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||||
|
builder := NewFilterChainBuilder()
|
||||||
|
assert.NotNil(t, builder.summaryVec)
|
||||||
|
|
||||||
|
filter := builder.FilterChain(func(ctx context.Context, inv *orm.Invocation) {
|
||||||
|
inv.Method = "coming"
|
||||||
|
})
|
||||||
|
assert.NotNil(t, filter)
|
||||||
|
|
||||||
|
inv := &orm.Invocation{}
|
||||||
|
filter(context.Background(), inv)
|
||||||
|
assert.Equal(t, "coming", inv.Method)
|
||||||
|
|
||||||
|
inv = &orm.Invocation{
|
||||||
|
Method: "Hello",
|
||||||
|
TxStartTime: time.Now(),
|
||||||
|
}
|
||||||
|
builder.reportTxn(context.Background(), inv)
|
||||||
|
|
||||||
|
inv = &orm.Invocation{
|
||||||
|
Method: "Begin",
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
// it will be ignored
|
||||||
|
builder.report(ctx, inv, time.Second)
|
||||||
|
|
||||||
|
inv.Method = "Commit"
|
||||||
|
builder.report(ctx, inv, time.Second)
|
||||||
|
|
||||||
|
inv.Method = "Update"
|
||||||
|
builder.report(ctx, inv, time.Second)
|
||||||
|
|
||||||
|
}
|
519
pkg/orm/filter_orm_decorator.go
Normal file
519
pkg/orm/filter_orm_decorator.go
Normal file
@ -0,0 +1,519 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TxNameKey = "TxName"
|
||||||
|
|
||||||
|
type filterOrmDecorator struct {
|
||||||
|
ormer
|
||||||
|
TxBeginner
|
||||||
|
TxCommitter
|
||||||
|
|
||||||
|
root Filter
|
||||||
|
|
||||||
|
insideTx bool
|
||||||
|
txStartTime time.Time
|
||||||
|
txName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFilterOrmDecorator(delegate Ormer, filterChains ...FilterChain) Ormer {
|
||||||
|
res := &filterOrmDecorator{
|
||||||
|
ormer: delegate,
|
||||||
|
TxBeginner: delegate,
|
||||||
|
root: func(ctx context.Context, inv *Invocation) {
|
||||||
|
inv.execute()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(filterChains) - 1; i >= 0; i-- {
|
||||||
|
node := filterChains[i]
|
||||||
|
res.root = node(res.root)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFilterTxOrmDecorator(delegate TxOrmer, root Filter, txName string) TxOrmer {
|
||||||
|
res := &filterOrmDecorator{
|
||||||
|
ormer: delegate,
|
||||||
|
TxCommitter: delegate,
|
||||||
|
root: root,
|
||||||
|
insideTx: true,
|
||||||
|
txStartTime: time.Now(),
|
||||||
|
txName: txName,
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Read(md interface{}, cols ...string) error {
|
||||||
|
return f.ReadWithCtx(context.Background(), md, cols...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) (err error) {
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "ReadWithCtx",
|
||||||
|
Args: []interface{}{md, cols},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
err = f.ormer.ReadWithCtx(ctx, md, cols...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error {
|
||||||
|
return f.ReadForUpdateWithCtx(context.Background(), md, cols...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
||||||
|
var err error
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "ReadForUpdateWithCtx",
|
||||||
|
Args: []interface{}{md, cols},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
err = f.ormer.ReadForUpdateWithCtx(ctx, md, cols...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||||
|
return f.ReadOrCreateWithCtx(context.Background(), md, col1, cols...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||||
|
var (
|
||||||
|
ok bool
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "ReadOrCreateWithCtx",
|
||||||
|
Args: []interface{}{md, col1, cols},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
ok, res, err = f.ormer.ReadOrCreateWithCtx(ctx, md, col1, cols...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return ok, res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
|
||||||
|
return f.LoadRelatedWithCtx(context.Background(), md, name, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...interface{}) (int64, error) {
|
||||||
|
var (
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "LoadRelatedWithCtx",
|
||||||
|
Args: []interface{}{md, name, args},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.ormer.LoadRelatedWithCtx(ctx, md, name, args...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer {
|
||||||
|
return f.QueryM2MWithCtx(context.Background(), md, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer {
|
||||||
|
var (
|
||||||
|
res QueryM2Mer
|
||||||
|
)
|
||||||
|
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "QueryM2MWithCtx",
|
||||||
|
Args: []interface{}{md, name},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res = f.ormer.QueryM2MWithCtx(ctx, md, name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QuerySeter {
|
||||||
|
return f.QueryTableWithCtx(context.Background(), ptrStructOrTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter {
|
||||||
|
var (
|
||||||
|
res QuerySeter
|
||||||
|
name string
|
||||||
|
md interface{}
|
||||||
|
mi *modelInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
if table, ok := ptrStructOrTableName.(string); ok {
|
||||||
|
name = table
|
||||||
|
} else {
|
||||||
|
name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName)))
|
||||||
|
md = ptrStructOrTableName
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, ok := modelCache.getByFullName(name); ok {
|
||||||
|
mi = m
|
||||||
|
}
|
||||||
|
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "QueryTableWithCtx",
|
||||||
|
Args: []interface{}{ptrStructOrTableName},
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
f: func() {
|
||||||
|
res = f.ormer.QueryTableWithCtx(ctx, ptrStructOrTableName)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) DBStats() *sql.DBStats {
|
||||||
|
var (
|
||||||
|
res *sql.DBStats
|
||||||
|
)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "DBStats",
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res = f.ormer.DBStats()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(context.Background(), inv)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) {
|
||||||
|
return f.InsertWithCtx(context.Background(), md)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
|
||||||
|
var (
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "InsertWithCtx",
|
||||||
|
Args: []interface{}{md},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.ormer.InsertWithCtx(ctx, md)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
|
||||||
|
return f.InsertOrUpdateWithCtx(context.Background(), md, colConflitAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
|
||||||
|
var (
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "InsertOrUpdateWithCtx",
|
||||||
|
Args: []interface{}{md, colConflitAndArgs},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.ormer.InsertOrUpdateWithCtx(ctx, md, colConflitAndArgs...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) InsertMulti(bulk int, mds interface{}) (int64, error) {
|
||||||
|
return f.InsertMultiWithCtx(context.Background(), bulk, mds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertMultiWithCtx uses the first element's model info
|
||||||
|
func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
|
||||||
|
var (
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
md interface{}
|
||||||
|
mi *modelInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
sind := reflect.Indirect(reflect.ValueOf(mds))
|
||||||
|
|
||||||
|
if (sind.Kind() == reflect.Array || sind.Kind() == reflect.Slice) && sind.Len() > 0 {
|
||||||
|
ind := reflect.Indirect(sind.Index(0))
|
||||||
|
md = ind.Interface()
|
||||||
|
mi, _ = modelCache.getByMd(md)
|
||||||
|
}
|
||||||
|
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "InsertMultiWithCtx",
|
||||||
|
Args: []interface{}{bulk, mds},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.ormer.InsertMultiWithCtx(ctx, bulk, mds)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, error) {
|
||||||
|
return f.UpdateWithCtx(context.Background(), md, cols...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
||||||
|
var (
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "UpdateWithCtx",
|
||||||
|
Args: []interface{}{md, cols},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.ormer.UpdateWithCtx(ctx, md, cols...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, error) {
|
||||||
|
return f.DeleteWithCtx(context.Background(), md, cols...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
||||||
|
var (
|
||||||
|
res int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
mi, _ := modelCache.getByMd(md)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "DeleteWithCtx",
|
||||||
|
Args: []interface{}{md, cols},
|
||||||
|
Md: md,
|
||||||
|
mi: mi,
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.ormer.DeleteWithCtx(ctx, md, cols...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Raw(query string, args ...interface{}) RawSeter {
|
||||||
|
return f.RawWithCtx(context.Background(), query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
|
||||||
|
var (
|
||||||
|
res RawSeter
|
||||||
|
)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "RawWithCtx",
|
||||||
|
Args: []interface{}{query, args},
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res = f.ormer.RawWithCtx(ctx, query, args...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Driver() Driver {
|
||||||
|
var (
|
||||||
|
res Driver
|
||||||
|
)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "Driver",
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res = f.ormer.Driver()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(context.Background(), inv)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Begin() (TxOrmer, error) {
|
||||||
|
return f.BeginWithCtxAndOpts(context.Background(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
|
||||||
|
return f.BeginWithCtxAndOpts(ctx, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
|
||||||
|
return f.BeginWithCtxAndOpts(context.Background(), opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
|
||||||
|
var (
|
||||||
|
res TxOrmer
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "BeginWithCtxAndOpts",
|
||||||
|
Args: []interface{}{opts},
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
f: func() {
|
||||||
|
res, err = f.TxBeginner.BeginWithCtxAndOpts(ctx, opts)
|
||||||
|
res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(ctx))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) DoTx(task func(txOrm TxOrmer) error) error {
|
||||||
|
return f.DoTxWithCtxAndOpts(context.Background(), nil, task)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error {
|
||||||
|
return f.DoTxWithCtxAndOpts(ctx, nil, task)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||||
|
return f.DoTxWithCtxAndOpts(context.Background(), opts, task)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "DoTxWithCtxAndOpts",
|
||||||
|
Args: []interface{}{opts, task},
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
TxName: getTxNameFromCtx(ctx),
|
||||||
|
f: func() {
|
||||||
|
err = f.TxBeginner.DoTxWithCtxAndOpts(ctx, opts, task)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(ctx, inv)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Commit() error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "Commit",
|
||||||
|
Args: []interface{}{},
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
TxName: f.txName,
|
||||||
|
f: func() {
|
||||||
|
err = f.TxCommitter.Commit()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(context.Background(), inv)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterOrmDecorator) Rollback() error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
inv := &Invocation{
|
||||||
|
Method: "Rollback",
|
||||||
|
Args: []interface{}{},
|
||||||
|
InsideTx: f.insideTx,
|
||||||
|
TxStartTime: f.txStartTime,
|
||||||
|
TxName: f.txName,
|
||||||
|
f: func() {
|
||||||
|
err = f.TxCommitter.Rollback()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f.root(context.Background(), inv)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTxNameFromCtx(ctx context.Context) string {
|
||||||
|
txName := ""
|
||||||
|
if n, ok := ctx.Value(TxNameKey).(string); ok {
|
||||||
|
txName = n
|
||||||
|
}
|
||||||
|
return txName
|
||||||
|
}
|
||||||
|
|
432
pkg/orm/filter_orm_decorator_test.go
Normal file
432
pkg/orm/filter_orm_decorator_test.go
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_Read(t *testing.T) {
|
||||||
|
|
||||||
|
register()
|
||||||
|
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "ReadWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
fte := &FilterTestEntity{}
|
||||||
|
err := od.Read(fte)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "read error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_BeginTx(t *testing.T) {
|
||||||
|
register()
|
||||||
|
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
if inv.Method == "BeginWithCtxAndOpts" {
|
||||||
|
assert.Equal(t, 1, len(inv.Args))
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
} else if inv.Method == "Commit" {
|
||||||
|
assert.Equal(t, 0, len(inv.Args))
|
||||||
|
assert.Equal(t, "Commit_tx", inv.TxName)
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.True(t, inv.InsideTx)
|
||||||
|
} else if inv.Method == "Rollback" {
|
||||||
|
assert.Equal(t, 0, len(inv.Args))
|
||||||
|
assert.Equal(t, "Rollback_tx", inv.TxName)
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.True(t, inv.InsideTx)
|
||||||
|
} else {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
to, err := od.Begin()
|
||||||
|
assert.True(t, validateBeginResult(t, to, err))
|
||||||
|
|
||||||
|
to, err = od.BeginWithOpts(nil)
|
||||||
|
assert.True(t, validateBeginResult(t, to, err))
|
||||||
|
|
||||||
|
ctx := context.WithValue(context.Background(), TxNameKey, "Commit_tx")
|
||||||
|
to, err = od.BeginWithCtx(ctx)
|
||||||
|
assert.True(t, validateBeginResult(t, to, err))
|
||||||
|
|
||||||
|
err = to.Commit()
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "commit", err.Error())
|
||||||
|
|
||||||
|
ctx = context.WithValue(context.Background(), TxNameKey, "Rollback_tx")
|
||||||
|
to, err = od.BeginWithCtxAndOpts(ctx, nil)
|
||||||
|
assert.True(t, validateBeginResult(t, to, err))
|
||||||
|
|
||||||
|
err = to.Rollback()
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "rollback", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_DBStats(t *testing.T) {
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "DBStats", inv.Method)
|
||||||
|
assert.Equal(t, 0, len(inv.Args))
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res := od.DBStats()
|
||||||
|
assert.NotNil(t, res)
|
||||||
|
assert.Equal(t, -1, res.MaxOpenConnections)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_Delete(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "DeleteWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res, err := od.Delete(&FilterTestEntity{})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "delete error", err.Error())
|
||||||
|
assert.Equal(t, int64(-2), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_DoTx(t *testing.T) {
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "DoTxWithCtxAndOpts", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
err := od.DoTx(func(txOrm TxOrmer) error {
|
||||||
|
return errors.New("tx error")
|
||||||
|
})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "tx error", err.Error())
|
||||||
|
|
||||||
|
err = od.DoTxWithCtx(context.Background(), func(txOrm TxOrmer) error {
|
||||||
|
return errors.New("tx ctx error")
|
||||||
|
})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "tx ctx error", err.Error())
|
||||||
|
|
||||||
|
err = od.DoTxWithOpts(nil, func(txOrm TxOrmer) error {
|
||||||
|
return errors.New("tx opts error")
|
||||||
|
})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "tx opts error", err.Error())
|
||||||
|
|
||||||
|
od = NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "DoTxWithCtxAndOpts", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.Equal(t, "do tx name", inv.TxName)
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx := context.WithValue(context.Background(), TxNameKey, "do tx name")
|
||||||
|
err = od.DoTxWithCtxAndOpts(ctx, nil, func(txOrm TxOrmer) error {
|
||||||
|
return errors.New("tx ctx opts error")
|
||||||
|
})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "tx ctx opts error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_Driver(t *testing.T) {
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "Driver", inv.Method)
|
||||||
|
assert.Equal(t, 0, len(inv.Args))
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res := od.Driver()
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_Insert(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "InsertWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 1, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
i, err := od.Insert(&FilterTestEntity{})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "insert error", err.Error())
|
||||||
|
assert.Equal(t, int64(100), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_InsertMulti(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "InsertMultiWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
bulk := []*FilterTestEntity{&FilterTestEntity{}, &FilterTestEntity{}}
|
||||||
|
i, err := od.InsertMulti(2, bulk)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "insert multi error", err.Error())
|
||||||
|
assert.Equal(t, int64(2), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_InsertOrUpdate(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "InsertOrUpdateWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
i, err := od.InsertOrUpdate(&FilterTestEntity{})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "insert or update error", err.Error())
|
||||||
|
assert.Equal(t, int64(1), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_LoadRelated(t *testing.T) {
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "LoadRelatedWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 3, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
i, err := od.LoadRelated(&FilterTestEntity{}, "hello")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "load related error", err.Error())
|
||||||
|
assert.Equal(t, int64(99), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_QueryM2M(t *testing.T) {
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "QueryM2MWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res := od.QueryM2M(&FilterTestEntity{}, "hello")
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_QueryTable(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "QueryTableWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 1, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res := od.QueryTable(&FilterTestEntity{})
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_Raw(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "RawWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res := od.Raw("hh")
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_ReadForUpdate(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "ReadForUpdateWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
err := od.ReadForUpdate(&FilterTestEntity{})
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "read for update error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterOrmDecorator_ReadOrCreate(t *testing.T) {
|
||||||
|
register()
|
||||||
|
o := &filterMockOrm{}
|
||||||
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
assert.Equal(t, "ReadOrCreateWithCtx", inv.Method)
|
||||||
|
assert.Equal(t, 3, len(inv.Args))
|
||||||
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
|
assert.False(t, inv.InsideTx)
|
||||||
|
next(ctx, inv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ok, i, err := od.ReadOrCreate(&FilterTestEntity{}, "name")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "read or create error", err.Error())
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Equal(t, int64(13), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterMockOrm is only used in this test file
|
||||||
|
type filterMockOrm struct {
|
||||||
|
DoNothingOrm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||||
|
return true, 13, errors.New("read or create error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
||||||
|
return errors.New("read for update error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...interface{}) (int64, error) {
|
||||||
|
return 99, errors.New("load related error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
|
||||||
|
return 1, errors.New("insert or update error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
|
||||||
|
return 2, errors.New("insert multi error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
|
||||||
|
return 100, errors.New("insert error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error {
|
||||||
|
return task(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
|
||||||
|
return -2, errors.New("delete error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
|
||||||
|
return &filterMockOrm{}, errors.New("begin tx")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
|
||||||
|
return errors.New("read error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) Commit() error {
|
||||||
|
return errors.New("commit")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) Rollback() error {
|
||||||
|
return errors.New("rollback")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterMockOrm) DBStats() *sql.DBStats {
|
||||||
|
return &sql.DBStats{
|
||||||
|
MaxOpenConnections: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateBeginResult(t *testing.T, to TxOrmer, err error) bool {
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, "begin tx", err.Error())
|
||||||
|
_, ok := to.(*filterOrmDecorator).TxCommitter.(*filterMockOrm)
|
||||||
|
assert.True(t, ok)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var filterTestEntityRegisterOnce sync.Once
|
||||||
|
|
||||||
|
type FilterTestEntity struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func register() {
|
||||||
|
filterTestEntityRegisterOnce.Do(func() {
|
||||||
|
RegisterModel(&FilterTestEntity{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FilterTestEntity) TableName() string {
|
||||||
|
return "FILTER_TEST"
|
||||||
|
}
|
31
pkg/orm/filter_test.go
Normal file
31
pkg/orm/filter_test.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAddGlobalFilterChain(t *testing.T) {
|
||||||
|
AddGlobalFilterChain(func(next Filter) Filter {
|
||||||
|
return func(ctx context.Context, inv *Invocation) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
assert.Equal(t, 1, len(globalFilterChains))
|
||||||
|
}
|
48
pkg/orm/invocation.go
Normal file
48
pkg/orm/invocation.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// 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 orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Invocation represents an "Orm" invocation
|
||||||
|
type Invocation struct {
|
||||||
|
Method string
|
||||||
|
// Md may be nil in some cases. It depends on method
|
||||||
|
Md interface{}
|
||||||
|
// the args are all arguments except context.Context
|
||||||
|
Args []interface{}
|
||||||
|
|
||||||
|
mi *modelInfo
|
||||||
|
// f is the Orm operation
|
||||||
|
f func()
|
||||||
|
|
||||||
|
// insideTx indicates whether this is inside a transaction
|
||||||
|
InsideTx bool
|
||||||
|
TxStartTime time.Time
|
||||||
|
TxName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inv *Invocation) GetTableName() string {
|
||||||
|
if inv.mi != nil{
|
||||||
|
return inv.mi.table
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inv *Invocation) execute() {
|
||||||
|
inv.f()
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
package orm
|
package orm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -73,6 +74,14 @@ func (mc *_modelCache) getByFullName(name string) (mi *modelInfo, ok bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc *_modelCache) getByMd(md interface{}) (*modelInfo, bool) {
|
||||||
|
val := reflect.ValueOf(md)
|
||||||
|
ind := reflect.Indirect(val)
|
||||||
|
typ := ind.Type()
|
||||||
|
name := getFullName(typ)
|
||||||
|
return mc.getByFullName(name)
|
||||||
|
}
|
||||||
|
|
||||||
// set model info to collection
|
// set model info to collection
|
||||||
func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
|
func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
|
||||||
mii := mc.cache[table]
|
mii := mc.cache[table]
|
||||||
|
@ -2486,3 +2486,5 @@ func TestInsertOrUpdate(t *testing.T) {
|
|||||||
throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status))
|
throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,17 +204,19 @@ type DriverGetter interface {
|
|||||||
Driver() Driver
|
Driver() Driver
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ormer interface {
|
type ormer interface {
|
||||||
DQL
|
DQL
|
||||||
DML
|
DML
|
||||||
DriverGetter
|
DriverGetter
|
||||||
|
}
|
||||||
|
|
||||||
|
type Ormer interface {
|
||||||
|
ormer
|
||||||
TxBeginner
|
TxBeginner
|
||||||
}
|
}
|
||||||
|
|
||||||
type TxOrmer interface {
|
type TxOrmer interface {
|
||||||
DQL
|
ormer
|
||||||
DML
|
|
||||||
DriverGetter
|
|
||||||
TxCommitter
|
TxCommitter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"golang.org/x/tools/go/packages"
|
||||||
"go/token"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -76,7 +75,7 @@ func init() {
|
|||||||
pkgLastupdate = make(map[string]int64)
|
pkgLastupdate = make(map[string]int64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parserPkg(pkgRealpath, pkgpath string) error {
|
func parserPkg(pkgRealpath string) error {
|
||||||
rep := strings.NewReplacer("\\", "_", "/", "_", ".", "_")
|
rep := strings.NewReplacer("\\", "_", "/", "_", ".", "_")
|
||||||
commentFilename, _ = filepath.Rel(AppPath, pkgRealpath)
|
commentFilename, _ = filepath.Rel(AppPath, pkgRealpath)
|
||||||
commentFilename = commentPrefix + rep.Replace(commentFilename) + ".go"
|
commentFilename = commentPrefix + rep.Replace(commentFilename) + ".go"
|
||||||
@ -85,24 +84,23 @@ func parserPkg(pkgRealpath, pkgpath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
genInfoList = make(map[string][]ControllerComments)
|
genInfoList = make(map[string][]ControllerComments)
|
||||||
fileSet := token.NewFileSet()
|
pkgs, err := packages.Load(&packages.Config{
|
||||||
astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool {
|
Mode: packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedSyntax,
|
||||||
name := info.Name()
|
Dir: pkgRealpath,
|
||||||
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
}, "./...")
|
||||||
}, parser.ParseComments)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, pkg := range astPkgs {
|
for _, pkg := range pkgs {
|
||||||
for _, fl := range pkg.Files {
|
for _, fl := range pkg.Syntax {
|
||||||
for _, d := range fl.Decls {
|
for _, d := range fl.Decls {
|
||||||
switch specDecl := d.(type) {
|
switch specDecl := d.(type) {
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
if specDecl.Recv != nil {
|
if specDecl.Recv != nil {
|
||||||
exp, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr) // Check that the type is correct first beforing throwing to parser
|
exp, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr) // Check that the type is correct first beforing throwing to parser
|
||||||
if ok {
|
if ok {
|
||||||
parserComments(specDecl, fmt.Sprint(exp.X), pkgpath)
|
parserComments(specDecl, fmt.Sprint(exp.X), pkg.PkgPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,8 +564,17 @@ func getpathTime(pkgRealpath string) (lastupdate int64, err error) {
|
|||||||
return lastupdate, err
|
return lastupdate, err
|
||||||
}
|
}
|
||||||
for _, f := range fl {
|
for _, f := range fl {
|
||||||
if lastupdate < f.ModTime().UnixNano() {
|
var t int64
|
||||||
lastupdate = f.ModTime().UnixNano()
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lastupdate, nil
|
return lastupdate, nil
|
||||||
|
@ -18,9 +18,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -257,45 +255,6 @@ 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 only when the Runmode is dev will generate router file in the router/auto.go from the controller
|
||||||
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
|
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
|
||||||
func (p *ControllerRegister) Include(cList ...ControllerInterface) {
|
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 {
|
for _, c := range cList {
|
||||||
reflectVal := reflect.ValueOf(c)
|
reflectVal := reflect.ValueOf(c)
|
||||||
t := reflect.Indirect(reflectVal).Type()
|
t := reflect.Indirect(reflectVal).Type()
|
||||||
|
@ -15,37 +15,44 @@
|
|||||||
package opentracing
|
package opentracing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
logKit "github.com/go-kit/kit/log"
|
||||||
|
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
|
|
||||||
beego "github.com/astaxie/beego/pkg"
|
beego "github.com/astaxie/beego/pkg"
|
||||||
"github.com/astaxie/beego/pkg/context"
|
beegoCtx "github.com/astaxie/beego/pkg/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
||||||
type FilterChainBuilder struct {
|
type FilterChainBuilder struct {
|
||||||
// CustomSpanFunc makes users to custom the span.
|
// CustomSpanFunc makes users to custom the span.
|
||||||
CustomSpanFunc func(span opentracing.Span, ctx *context.Context)
|
CustomSpanFunc func(span opentracing.Span, ctx *beegoCtx.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc {
|
func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc {
|
||||||
return func(ctx *context.Context) {
|
return func(ctx *beegoCtx.Context) {
|
||||||
span := opentracing.SpanFromContext(ctx.Request.Context())
|
var (
|
||||||
spanCtx := ctx.Request.Context()
|
spanCtx context.Context
|
||||||
if span == nil {
|
span opentracing.Span
|
||||||
operationName := ctx.Input.URL()
|
)
|
||||||
// it means that there is not any span, so we create a span as the root span.
|
operationName := builder.operationName(ctx)
|
||||||
// TODO, if we support multiple servers, this need to be changed
|
|
||||||
route, found := beego.BeeApp.Handlers.FindRouter(ctx)
|
if preSpan := opentracing.SpanFromContext(ctx.Request.Context()); preSpan == nil {
|
||||||
if found {
|
inject := opentracingKit.HTTPToContext(opentracing.GlobalTracer(), operationName, logKit.NewNopLogger())
|
||||||
operationName = route.GetPattern()
|
spanCtx = inject(ctx.Request.Context(), ctx.Request)
|
||||||
}
|
span = opentracing.SpanFromContext(spanCtx)
|
||||||
span, spanCtx = opentracing.StartSpanFromContext(spanCtx, operationName)
|
} else {
|
||||||
newReq := ctx.Request.Clone(spanCtx)
|
span, spanCtx = opentracing.StartSpanFromContext(ctx.Request.Context(), operationName)
|
||||||
ctx.Reset(ctx.ResponseWriter.ResponseWriter, newReq)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
|
newReq := ctx.Request.Clone(spanCtx)
|
||||||
|
ctx.Reset(ctx.ResponseWriter.ResponseWriter, newReq)
|
||||||
|
|
||||||
next(ctx)
|
next(ctx)
|
||||||
// if you think we need to do more things, feel free to create an issue to tell us
|
// if you think we need to do more things, feel free to create an issue to tell us
|
||||||
span.SetTag("status", ctx.Output.Status)
|
span.SetTag("status", ctx.Output.Status)
|
||||||
@ -56,3 +63,14 @@ func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.Filt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 := beego.BeeApp.Handlers.FindRouter(ctx)
|
||||||
|
if found {
|
||||||
|
operationName = route.GetPattern()
|
||||||
|
}
|
||||||
|
return operationName
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user