1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 02:00:55 +00:00
This commit is contained in:
Ming Deng 2020-08-29 01:17:43 +08:00
parent c2361170b3
commit 81b9a1382a
11 changed files with 215 additions and 57 deletions

View File

@ -7,7 +7,7 @@ services:
- mysql - mysql
- postgresql - postgresql
- memcached - memcached
- etcd - docker
env: env:
global: global:
- GO_REPO_FULLNAME="github.com/astaxie/beego" - GO_REPO_FULLNAME="github.com/astaxie/beego"
@ -27,17 +27,33 @@ before_install:
- cd ssdb - cd ssdb
- make - make
- cd .. - cd ..
# - prepare etcd
# - prepare for etcd unit tests # - prepare for etcd unit tests
- git clone https://github.com/etcd-io/etcd.git - rm -rf /tmp/etcd-data.tmp
- cd etcd - mkdir -p /tmp/etcd-data.tmp
- ./build - docker rmi gcr.io/etcd-development/etcd:v3.3.25 || true &&
- ./bin/etcd docker run -d
- ./bin/etcdctl put current.float 1.23 -p 2379:2379
- ./bin/etcdctl put current.bool true -p 2380:2380
- ./bin/etcdctl put current.int 11 --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data
- ./bin/etcdctl put current.string hello --name etcd-gcr-v3.3.25
- ./bin/etcdctl put current.serialize.name test gcr.io/etcd-development/etcd:v3.3.25
- cd .. /usr/local/bin/etcd
--name s1
--data-dir /etcd-data
--listen-client-urls http://0.0.0.0:2379
--advertise-client-urls http://0.0.0.0:2379
--listen-peer-urls http://0.0.0.0:2380
--initial-advertise-peer-urls http://0.0.0.0:2380
--initial-cluster s1=http://0.0.0.0:2380
--initial-cluster-token tkn
--initial-cluster-state new
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23"
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true"
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11"
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello"
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test"
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key"
install: install:
- go get github.com/lib/pq - go get github.com/lib/pq
- go get github.com/go-sql-driver/mysql - go get github.com/go-sql-driver/mysql
@ -64,6 +80,8 @@ install:
- go get -u golang.org/x/lint/golint - go get -u golang.org/x/lint/golint
- go get -u github.com/go-redis/redis - go get -u github.com/go-redis/redis
before_script: before_script:
# -
- psql --version - psql --version
# - prepare for orm unit tests # - prepare for orm unit tests
- sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"

View File

@ -34,7 +34,10 @@ func getPort() string {
if err != nil { if err != nil {
return "8080" return "8080"
} }
port = config.String("httpport") port, err = config.String("httpport")
if err != nil {
return "8080"
}
return port return port
} }
return port return port

View File

@ -131,7 +131,7 @@ func (c *BaseConfiger) Float(key string) (float64, error) {
// DefaultString returns the string value for a given key. // DefaultString returns the string value for a given key.
// if err != nil or value is empty return defaultval // if err != nil or value is empty return defaultval
func (c *BaseConfiger) DefaultString(key string, defaultVal string) string { func (c *BaseConfiger) DefaultString(key string, defaultVal string) string {
if res, err := c.String(key); res != "" && err != nil { if res, err := c.String(key); res != "" && err == nil {
return res return res
} }
return defaultVal return defaultVal
@ -140,7 +140,7 @@ func (c *BaseConfiger) DefaultString(key string, defaultVal 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
func (c *BaseConfiger) DefaultStrings(key string, defaultVal []string) []string { func (c *BaseConfiger) DefaultStrings(key string, defaultVal []string) []string {
if res, err := c.Strings(key); len(res) > 0 && err != nil { if res, err := c.Strings(key); len(res) > 0 && err == nil {
return res return res
} }
return defaultVal return defaultVal

View File

@ -17,14 +17,13 @@ package config
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"errors" "errors"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"os/user" "os/user"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"sync" "sync"
) )
@ -66,9 +65,6 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
keyComment: make(map[string]string), keyComment: make(map[string]string),
RWMutex: sync.RWMutex{}, RWMutex: sync.RWMutex{},
} }
cfg.BaseConfiger = NewBaseConfiger(func(ctx context.Context, key string) (string, error) {
return cfg.getdata(key)
})
cfg.Lock() cfg.Lock()
defer cfg.Unlock() defer cfg.Unlock()
@ -94,7 +90,7 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
break break
} }
// It might be a good idea to throw a error on all unknonw errors? //It might be a good idea to throw a error on all unknonw errors?
if _, ok := err.(*os.PathError); ok { if _, ok := err.(*os.PathError); ok {
return nil, err return nil, err
} }
@ -236,6 +232,101 @@ type IniConfigContainer struct {
sync.RWMutex sync.RWMutex
} }
// Bool returns the boolean value for a given key.
func (c *IniConfigContainer) Bool(key string) (bool, error) {
return ParseBool(c.getdata(key))
}
// DefaultBool returns the boolean value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
v, err := c.Bool(key)
if err != nil {
return defaultval
}
return v
}
// Int returns the integer value for a given key.
func (c *IniConfigContainer) Int(key string) (int, error) {
return strconv.Atoi(c.getdata(key))
}
// DefaultInt returns the integer value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
v, err := c.Int(key)
if err != nil {
return defaultval
}
return v
}
// Int64 returns the int64 value for a given key.
func (c *IniConfigContainer) Int64(key string) (int64, error) {
return strconv.ParseInt(c.getdata(key), 10, 64)
}
// DefaultInt64 returns the int64 value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
v, err := c.Int64(key)
if err != nil {
return defaultval
}
return v
}
// Float returns the float value for a given key.
func (c *IniConfigContainer) Float(key string) (float64, error) {
return strconv.ParseFloat(c.getdata(key), 64)
}
// DefaultFloat returns the float64 value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
v, err := c.Float(key)
if err != nil {
return defaultval
}
return v
}
// String returns the string value for a given key.
func (c *IniConfigContainer) String(key string) (string, error) {
return c.getdata(key), nil
}
// DefaultString returns the string value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultString(key string, defaultval string) string {
v, err := c.String(key)
if v == "" || err != nil {
return defaultval
}
return v
}
// Strings returns the []string value for a given key.
// Return nil if config value does not exist or is empty.
func (c *IniConfigContainer) Strings(key string) ([]string, error) {
v, err := c.String(key)
if v == "" || err != nil {
return nil, err
}
return strings.Split(v, ";"), nil
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
v, err := c.Strings(key)
if v == nil || err != nil {
return defaultval
}
return v
}
// GetSection returns map for the given section // GetSection returns map for the given section
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 {
@ -383,9 +474,9 @@ func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) {
} }
// section.key or key // section.key or key
func (c *IniConfigContainer) getdata(key string) (string, error) { func (c *IniConfigContainer) getdata(key string) string {
if len(key) == 0 { if len(key) == 0 {
return "", errors.New("the key is empty") return ""
} }
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
@ -403,10 +494,10 @@ func (c *IniConfigContainer) getdata(key string) (string, error) {
} }
if v, ok := c.data[section]; ok { if v, ok := c.data[section]; ok {
if vv, ok := v[k]; ok { if vv, ok := v[k]; ok {
return vv, nil return vv
} }
} }
return "", errors.New(fmt.Sprintf("config not found: %s", key)) return ""
} }
func init() { func init() {

View File

@ -165,7 +165,35 @@ func (c *JSONConfigContainer) String(key string) (string, error) {
return v, nil return v, nil
} }
} }
return "", errors.New(fmt.Sprintf("config not found or is not string, key: %s", key)) return "", nil
}
// DefaultString returns the string value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultString(key string, defaultval string) string {
// TODO FIXME should not use "" to replace non existence
if v, err := c.String(key); v != "" && err == nil {
return v
}
return defaultval
}
// Strings returns the []string value for a given key.
func (c *JSONConfigContainer) Strings(key string) ([]string, error) {
stringVal, err := c.String(key)
if stringVal == "" || err != nil {
return nil, err
}
return strings.Split(stringVal, ";"), nil
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
if v, err := c.Strings(key); v != nil && err == nil {
return v
}
return defaultval
} }
// GetSection returns map for the given section // GetSection returns map for the given section

View File

@ -26,7 +26,7 @@
// //
// cnf, err := config.NewConfig("xml", "config.xml") // cnf, err := config.NewConfig("xml", "config.xml")
// //
// More docs http://beego.me/docs/module/config.md //More docs http://beego.me/docs/module/config.md
package xml package xml
import ( import (
@ -36,11 +36,11 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"strconv" "strconv"
"strings"
"sync" "sync"
"github.com/beego/x2j"
"github.com/astaxie/beego/pkg/infrastructure/config" "github.com/astaxie/beego/pkg/infrastructure/config"
"github.com/beego/x2j"
) )
// Config is a xml config parser and implements Config interface. // Config is a xml config parser and implements Config interface.
@ -148,7 +148,7 @@ func (c *ConfigContainer) String(key string) (string, error) {
if v, ok := c.data[key].(string); ok { if v, ok := c.data[key].(string); ok {
return v, nil return v, nil
} }
return "", errors.New(fmt.Sprintf("configuration not found or not string, key: %s", key)) return "", nil
} }
// DefaultString returns the string value for a given key. // DefaultString returns the string value for a given key.
@ -161,6 +161,25 @@ func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
return v return v
} }
// Strings returns the []string value for a given key.
func (c *ConfigContainer) Strings(key string) ([]string, error) {
v, err := c.String(key)
if v == "" || err != nil {
return nil, err
}
return strings.Split(v, ";"), nil
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
v, err := c.Strings(key)
if v == nil || err != nil {
return defaultval
}
return v
}
// GetSection returns map for the given section // GetSection returns map for the given section
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 {

View File

@ -214,11 +214,9 @@ func (c *ConfigContainer) String(key string) (string, error) {
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 {
return vv, nil return vv, nil
} else {
return "", errors.New(fmt.Sprintf("the value is not string, key: %s, value: %v", key, v))
} }
} }
return "", errors.New(fmt.Sprintf("configuration not found, key: %s", key)) return "", nil
} }
// DefaultString returns the string value for a given key. // DefaultString returns the string value for a given key.

View File

@ -32,8 +32,8 @@ import (
// Config is the main struct for BConfig // Config is the main struct for BConfig
type Config struct { type Config struct {
AppName string //Application name AppName string // Application name
RunMode string //Running Mode: dev | prod RunMode string // Running Mode: dev | prod
RouterCaseSensitive bool RouterCaseSensitive bool
ServerName string ServerName string
RecoverPanic bool RecoverPanic bool
@ -113,8 +113,8 @@ type SessionConfig struct {
// LogConfig holds Log related config // LogConfig holds Log related config
type LogConfig struct { type LogConfig struct {
AccessLogs bool AccessLogs bool
EnableStaticLogs bool //log static files requests default: false EnableStaticLogs bool // log static files requests default: false
AccessLogsFormat string //access log format: JSON_FORMAT, APACHE_FORMAT or empty string AccessLogsFormat string // access log format: JSON_FORMAT, APACHE_FORMAT or empty string
FileLineNum bool FileLineNum bool
Outputs map[string]string // Store Adaptor : config Outputs map[string]string // Store Adaptor : config
} }
@ -210,7 +210,7 @@ func newBConfig() *Config {
RecoverFunc: recoverPanic, RecoverFunc: recoverPanic,
CopyRequestBody: false, CopyRequestBody: false,
EnableGzip: false, EnableGzip: false,
MaxMemory: 1 << 26, //64MB MaxMemory: 1 << 26, // 64MB
EnableErrorsShow: true, EnableErrorsShow: true,
EnableErrorsRender: true, EnableErrorsRender: true,
Listen: Listen{ Listen: Listen{
@ -258,7 +258,7 @@ func newBConfig() *Config {
SessionGCMaxLifetime: 3600, SessionGCMaxLifetime: 3600,
SessionProviderConfig: "", SessionProviderConfig: "",
SessionDisableHTTPOnly: false, SessionDisableHTTPOnly: false,
SessionCookieLifeTime: 0, //set cookie default is the browser life SessionCookieLifeTime: 0, // set cookie default is the browser life
SessionAutoSetCookie: true, SessionAutoSetCookie: true,
SessionDomain: "", SessionDomain: "",
SessionEnableSidInHTTPHeader: false, // enable store/get the sessionId into/from http headers SessionEnableSidInHTTPHeader: false, // enable store/get the sessionId into/from http headers
@ -292,11 +292,11 @@ func assignConfig(ac config.Configer) error {
// set the run mode first // set the run mode first
if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" { if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
BConfig.RunMode = envRunMode BConfig.RunMode = envRunMode
} else if runMode := ac.String("RunMode"); runMode != "" { } else if runMode, err := ac.String("RunMode"); runMode != "" && err == nil {
BConfig.RunMode = runMode BConfig.RunMode = runMode
} }
if sd := ac.String("StaticDir"); sd != "" { if sd, err := ac.String("StaticDir"); sd != "" && err == nil {
BConfig.WebConfig.StaticDir = map[string]string{} BConfig.WebConfig.StaticDir = map[string]string{}
sds := strings.Fields(sd) sds := strings.Fields(sd)
for _, v := range sds { for _, v := range sds {
@ -308,7 +308,7 @@ func assignConfig(ac config.Configer) error {
} }
} }
if sgz := ac.String("StaticExtensionsToGzip"); sgz != "" { if sgz, err := ac.String("StaticExtensionsToGzip"); sgz != "" && err == nil {
extensions := strings.Split(sgz, ",") extensions := strings.Split(sgz, ",")
fileExts := []string{} fileExts := []string{}
for _, ext := range extensions { for _, ext := range extensions {
@ -334,7 +334,7 @@ func assignConfig(ac config.Configer) error {
BConfig.WebConfig.StaticCacheFileNum = sfn BConfig.WebConfig.StaticCacheFileNum = sfn
} }
if lo := ac.String("LogOutputs"); lo != "" { if lo, err := ac.String("LogOutputs"); lo != "" && err == nil {
// if lo is not nil or empty // if lo is not nil or empty
// means user has set his own LogOutputs // means user has set his own LogOutputs
// clear the default setting to BConfig.Log.Outputs // clear the default setting to BConfig.Log.Outputs
@ -349,7 +349,7 @@ func assignConfig(ac config.Configer) error {
} }
} }
//init log // init log
logs.Reset() logs.Reset()
for adaptor, config := range BConfig.Log.Outputs { for adaptor, config := range BConfig.Log.Outputs {
err := logs.SetLogger(adaptor, config) err := logs.SetLogger(adaptor, config)
@ -388,7 +388,7 @@ func assignSingleConfig(p interface{}, ac config.Configer) {
pf.SetBool(ac.DefaultBool(name, pf.Bool())) pf.SetBool(ac.DefaultBool(name, pf.Bool()))
case reflect.Struct: case reflect.Struct:
default: default:
//do nothing here // do nothing here
} }
} }
@ -431,16 +431,16 @@ func (b *beegoAppConfig) Set(key, val string) error {
return nil return nil
} }
func (b *beegoAppConfig) String(key string) string { func (b *beegoAppConfig) String(key string) (string, error) {
if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" { if v, err := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" && err == nil {
return v return v, nil
} }
return b.innerConfig.String(key) return b.innerConfig.String(key)
} }
func (b *beegoAppConfig) Strings(key string) []string { func (b *beegoAppConfig) Strings(key string) ([]string, error) {
if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 { if v, err := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 && err == nil {
return v return v, nil
} }
return b.innerConfig.Strings(key) return b.innerConfig.Strings(key)
} }
@ -474,14 +474,14 @@ func (b *beegoAppConfig) Float(key string) (float64, error) {
} }
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string { func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
if v := b.String(key); v != "" { if v, err := b.String(key); v != "" && err == nil {
return v return v
} }
return defaultVal return defaultVal
} }
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string { func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
if v := b.Strings(key); len(v) != 0 { if v, err := b.Strings(key); len(v) != 0 && err == nil {
return v return v
} }
return defaultVal return defaultVal

View File

@ -48,9 +48,9 @@ func registerDefaultErrorHandler() error {
func registerSession() error { func registerSession() error {
if BConfig.WebConfig.Session.SessionOn { if BConfig.WebConfig.Session.SessionOn {
var err error var err error
sessionConfig := AppConfig.String("sessionConfig") sessionConfig, err := AppConfig.String("sessionConfig")
conf := new(session.ManagerConfig) conf := new(session.ManagerConfig)
if sessionConfig == "" { if sessionConfig == "" || err != nil {
conf.CookieName = BConfig.WebConfig.Session.SessionName conf.CookieName = BConfig.WebConfig.Session.SessionName
conf.EnableSetCookie = BConfig.WebConfig.Session.SessionAutoSetCookie conf.EnableSetCookie = BConfig.WebConfig.Session.SessionAutoSetCookie
conf.Gclifetime = BConfig.WebConfig.Session.SessionGCMaxLifetime conf.Gclifetime = BConfig.WebConfig.Session.SessionGCMaxLifetime

View File

@ -160,7 +160,7 @@ func NotNil(a interface{}) (isNil bool) {
func GetConfig(returnType, key string, defaultVal interface{}) (value interface{}, err error) { func GetConfig(returnType, key string, defaultVal interface{}) (value interface{}, err error) {
switch returnType { switch returnType {
case "String": case "String":
value = AppConfig.String(key) value, err = AppConfig.String(key)
case "Bool": case "Bool":
value, err = AppConfig.Bool(key) value, err = AppConfig.Bool(key)
case "Int": case "Int":

View File

@ -5,3 +5,4 @@ etcdctl put current.bool true
etcdctl put current.int 11 etcdctl put current.int 11
etcdctl put current.string hello etcdctl put current.string hello
etcdctl put current.serialize.name test etcdctl put current.serialize.name test
etcdctl put sub.sub.key1 sub.sub.key