mirror of
https://gitee.com/johng/gf.git
synced 2024-11-30 03:07:45 +08:00
update travis for adding mysql password; add custom view feature for ghttp.Response
This commit is contained in:
parent
a4f191c1c6
commit
ad540f7c25
@ -32,6 +32,7 @@ install:
|
||||
before_script:
|
||||
- find . -name "*.go" | xargs gofmt -w
|
||||
- git diff --name-only --exit-code || exit 1
|
||||
- echo "USE mysql;\nUPDATE user SET password=PASSWORD('12345678') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root
|
||||
- psql -c 'create database travis_ci_test;' -U postgres
|
||||
|
||||
script:
|
||||
|
@ -16,7 +16,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// 数据库对象/接口
|
||||
msdb gdb.DB
|
||||
)
|
||||
|
||||
@ -44,7 +43,6 @@ func InitMssql() {
|
||||
msdb = r
|
||||
}
|
||||
|
||||
// 创建默认用户表
|
||||
createTableMssql("t_user")
|
||||
//msdb.SetDebug(true)
|
||||
}
|
||||
@ -74,7 +72,6 @@ func createTableMssql(table ...string) (name string) {
|
||||
//msdb.Exec("DROP DATABASE test")
|
||||
//msdb.Exec("CREATE DATABASE test")
|
||||
|
||||
// 选择操作数据库
|
||||
msdb.SetSchema("test")
|
||||
|
||||
//msdb.SetDebug(true)
|
||||
@ -102,7 +99,6 @@ func createInitTableMssql(table ...string) (name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 删除指定表.
|
||||
func dropTableMssql(table string) {
|
||||
if _, err := msdb.Exec(fmt.Sprintf(`
|
||||
IF EXISTS (SELECT * FROM sysobjects WHERE name='%s' and xtype='U')
|
||||
|
@ -8,8 +8,6 @@ package gdb_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
|
||||
@ -19,25 +17,22 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
INIT_DATA_SIZE = 10 // 初始化表数据量
|
||||
TABLE = "user" // 测试数据表
|
||||
SCHEMA1 = "test1" // 测试数据库1
|
||||
SCHEMA2 = "test2" // 测试数据库2
|
||||
INIT_DATA_SIZE = 10
|
||||
TABLE = "user"
|
||||
SCHEMA1 = "test1"
|
||||
SCHEMA2 = "test2"
|
||||
)
|
||||
|
||||
var (
|
||||
// 测试包变量,ORM对象
|
||||
db gdb.DB
|
||||
)
|
||||
|
||||
// 初始化连接参数。
|
||||
// 测试前需要修改连接参数。
|
||||
func InitMysql() {
|
||||
node := gdb.ConfigNode{
|
||||
Host: "127.0.0.1",
|
||||
Port: "3306",
|
||||
User: "root",
|
||||
Pass: "",
|
||||
Pass: "12345678",
|
||||
Name: "",
|
||||
Type: "mysql",
|
||||
Role: "master",
|
||||
@ -47,10 +42,6 @@ func InitMysql() {
|
||||
MaxOpenConnCount: 10,
|
||||
MaxConnLifetime: 600,
|
||||
}
|
||||
// 作者本地测试hack
|
||||
if hostname, _ := os.Hostname(); hostname == "ijohn" {
|
||||
node.Pass = "12345678"
|
||||
}
|
||||
gdb.AddConfigNode("test", node)
|
||||
gdb.AddConfigNode(gdb.DEFAULT_GROUP_NAME, node)
|
||||
if r, err := gdb.New(); err != nil {
|
||||
@ -58,24 +49,21 @@ func InitMysql() {
|
||||
} else {
|
||||
db = r
|
||||
}
|
||||
// 准备测试数据结构:数据库
|
||||
|
||||
schemaTemplate := "CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET UTF8"
|
||||
if _, err := db.Exec(fmt.Sprintf(schemaTemplate, SCHEMA1)); err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
// 多个数据库,用于测试数据库切换
|
||||
|
||||
if _, err := db.Exec(fmt.Sprintf(schemaTemplate, SCHEMA2)); err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
// 设置默认操作数据库
|
||||
|
||||
db.SetSchema(SCHEMA1)
|
||||
// 创建默认用户表
|
||||
|
||||
createTable(TABLE)
|
||||
}
|
||||
|
||||
// 创建指定名称的user测试表,当table为空时,创建随机的表名。
|
||||
// 创建的测试表默认没有任何数据。
|
||||
// 执行完成后返回该表名。
|
||||
func createTable(table ...string) (name string) {
|
||||
if len(table) > 0 {
|
||||
name = table[0]
|
||||
@ -85,11 +73,11 @@ func createTable(table ...string) (name string) {
|
||||
dropTable(name)
|
||||
if _, err := db.Exec(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
|
||||
passport varchar(45) NULL COMMENT '账号',
|
||||
password char(32) NULL COMMENT '密码',
|
||||
nickname varchar(45) NULL COMMENT '昵称',
|
||||
create_time timestamp NULL COMMENT '创建时间/注册时间',
|
||||
id int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
passport varchar(45) NULL,
|
||||
password char(32) NULL,
|
||||
nickname varchar(45) NULL,
|
||||
create_time timestamp NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`, name)); err != nil {
|
||||
@ -98,7 +86,6 @@ func createTable(table ...string) (name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建测试表,并初始化默认数据。
|
||||
func createInitTable(table ...string) (name string) {
|
||||
name = createTable(table...)
|
||||
array := garray.New(true)
|
||||
@ -120,7 +107,6 @@ func createInitTable(table ...string) (name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 删除指定表.
|
||||
func dropTable(table string) {
|
||||
if _, err := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)); err != nil {
|
||||
gtest.Error(err)
|
||||
|
@ -17,7 +17,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// 数据库对象/接口
|
||||
oradb gdb.DB
|
||||
)
|
||||
|
||||
@ -46,7 +45,6 @@ func InitOracle() {
|
||||
oradb = r
|
||||
}
|
||||
|
||||
// 创建默认用户表
|
||||
createTableOracle("t_user")
|
||||
}
|
||||
|
||||
@ -94,7 +92,6 @@ func createInitTableOracle(table ...string) (name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 删除指定表.
|
||||
func dropTableOracle(table string) {
|
||||
|
||||
count, err := oradb.GetCount("SELECT COUNT(*) FROM USER_TABLES WHERE TABLE_NAME = ?", strings.ToUpper(table))
|
||||
|
@ -16,12 +16,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// 数据库对象/接口
|
||||
pgdb gdb.DB
|
||||
)
|
||||
|
||||
// 初始化连接参数。
|
||||
// 测试前需要修改连接参数。
|
||||
func InitPgsql() {
|
||||
node := gdb.ConfigNode{
|
||||
Host: "127.0.0.1",
|
||||
@ -64,10 +61,6 @@ func InitPgsql() {
|
||||
|
||||
}
|
||||
|
||||
// 创建指定名称的user测试表,当table为空时,创建随机的表名。
|
||||
// 创建的测试表默认没有任何数据。
|
||||
// 执行完成后返回该表名。
|
||||
// TODO 支持更多数据库
|
||||
func createTablePgsql(table ...string) (name string) {
|
||||
if len(table) > 0 {
|
||||
name = table[0]
|
||||
@ -91,7 +84,6 @@ func createTablePgsql(table ...string) (name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建测试表,并初始化默认数据。
|
||||
func createInitTablePgsql(table ...string) (name string) {
|
||||
name = createTablePgsql(table...)
|
||||
array := garray.New(true)
|
||||
@ -113,7 +105,6 @@ func createInitTablePgsql(table ...string) (name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 删除指定表.
|
||||
func dropTablePgsql(table string) {
|
||||
if _, err := pgdb.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s", table)); err != nil {
|
||||
gtest.Fatal(err)
|
||||
|
@ -315,6 +315,9 @@ func Test_Model_Safe(t *testing.T) {
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
md1 := db.Table(table).Where("id>", 0).Safe()
|
||||
md2 := md1.Where("id in (?)", g.Slice{1, 3})
|
||||
md3 := md1.Where("id in (?)", g.Slice{4, 5, 6})
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/os/gview"
|
||||
"net/http"
|
||||
|
||||
"github.com/gogf/gf/os/gres"
|
||||
@ -20,13 +21,14 @@ import (
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
)
|
||||
|
||||
// Response is the writer for response buffer.
|
||||
// Response is the http response manager.
|
||||
// Note that it implements the http.ResponseWriter interface with buffering feature.
|
||||
type Response struct {
|
||||
*ResponseWriter // Underlying ResponseWriter.
|
||||
Server *Server // Parent server.
|
||||
Writer *ResponseWriter // Alias of ResponseWriter.
|
||||
Request *Request // According request.
|
||||
view *gview.View // Custom template view engine object for this response.
|
||||
}
|
||||
|
||||
// newResponse creates and returns a new Response object.
|
||||
@ -162,7 +164,7 @@ func (r *Response) ServeFile(path string, allowIndex ...bool) {
|
||||
r.Server.serveFile(r.Request, serveFile, allowIndex...)
|
||||
}
|
||||
|
||||
// ServeFileDownload serves file as file downloading to the response.
|
||||
// ServeFileDownload serves file downloading to the response.
|
||||
func (r *Response) ServeFileDownload(path string, name ...string) {
|
||||
serveFile := (*staticServeFile)(nil)
|
||||
downloadName := ""
|
||||
@ -194,29 +196,29 @@ func (r *Response) ServeFileDownload(path string, name ...string) {
|
||||
r.Server.serveFile(r.Request, serveFile)
|
||||
}
|
||||
|
||||
// RedirectTo redirects client to another location.
|
||||
// RedirectTo redirects client to another location using http status 302.
|
||||
func (r *Response) RedirectTo(location string) {
|
||||
r.Header().Set("Location", location)
|
||||
r.WriteHeader(http.StatusFound)
|
||||
r.Request.Exit()
|
||||
}
|
||||
|
||||
// RedirectBack redirects client back to referer.
|
||||
// RedirectBack redirects client back to referer using http status 302.
|
||||
func (r *Response) RedirectBack() {
|
||||
r.RedirectTo(r.Request.GetReferer())
|
||||
}
|
||||
|
||||
// BufferString returns the buffer content as []byte.
|
||||
// BufferString returns the buffered content as []byte.
|
||||
func (r *Response) Buffer() []byte {
|
||||
return r.buffer.Bytes()
|
||||
}
|
||||
|
||||
// BufferString returns the buffer content as string.
|
||||
// BufferString returns the buffered content as string.
|
||||
func (r *Response) BufferString() string {
|
||||
return r.buffer.String()
|
||||
}
|
||||
|
||||
// BufferLength returns the length of the buffer content.
|
||||
// BufferLength returns the length of the buffered content.
|
||||
func (r *Response) BufferLength() int {
|
||||
return r.buffer.Len()
|
||||
}
|
||||
@ -237,6 +239,5 @@ func (r *Response) Output() {
|
||||
if r.Server.config.ServerAgent != "" {
|
||||
r.Header().Set("Server", r.Server.config.ServerAgent)
|
||||
}
|
||||
//r.handleGzip()
|
||||
r.Writer.OutputBuffer()
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
)
|
||||
|
||||
// CORSOptions is the options for CORS feature.
|
||||
// See https://www.w3.org/TR/cors/ .
|
||||
type CORSOptions struct {
|
||||
AllowDomain []string // Used for allowing requests from custom domains
|
||||
@ -70,7 +71,7 @@ func (r *Response) CORS(options CORSOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
// CORSAllowed checks whether the current request origin is allowed CORS.
|
||||
// CORSAllowed checks whether the current request origin is allowed cross-domain.
|
||||
func (r *Response) CORSAllowedOrigin(options CORSOptions) bool {
|
||||
if options.AllowDomain == nil {
|
||||
return true
|
||||
|
@ -13,7 +13,25 @@ import (
|
||||
"github.com/gogf/gf/util/gmode"
|
||||
)
|
||||
|
||||
// 展示模板,可以给定模板参数,及临时的自定义模板函数
|
||||
// SetView sets template view engine object for this response.
|
||||
func (r *Response) SetView(view *gview.View) {
|
||||
r.view = view
|
||||
}
|
||||
|
||||
// GetView returns the template view engine object for this response.
|
||||
func (r *Response) GetView() *gview.View {
|
||||
view := r.view
|
||||
if view == nil {
|
||||
view = r.Server.config.View
|
||||
}
|
||||
if view == nil {
|
||||
gview.Instance()
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
// WriteTpl parses and responses given template file.
|
||||
// The parameter <params> specifies the template variables for parsing.
|
||||
func (r *Response) WriteTpl(tpl string, params ...gview.Params) error {
|
||||
if b, err := r.ParseTpl(tpl, params...); err != nil {
|
||||
if !gmode.IsProduct() {
|
||||
@ -26,7 +44,22 @@ func (r *Response) WriteTpl(tpl string, params ...gview.Params) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 展示模板内容,可以给定模板参数,及临时的自定义模板函数
|
||||
// WriteTplDefault parses and responses the default template file.
|
||||
// The parameter <params> specifies the template variables for parsing.
|
||||
func (r *Response) WriteTplDefault(params ...gview.Params) error {
|
||||
if b, err := r.ParseTplDefault(params...); err != nil {
|
||||
if !gmode.IsProduct() {
|
||||
r.Write("Template Parsing Error: " + err.Error())
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
r.Write(b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteTplContent parses and responses the template content.
|
||||
// The parameter <params> specifies the template variables for parsing.
|
||||
func (r *Response) WriteTplContent(content string, params ...gview.Params) error {
|
||||
if b, err := r.ParseTplContent(content, params...); err != nil {
|
||||
if !gmode.IsProduct() {
|
||||
@ -39,23 +72,24 @@ func (r *Response) WriteTplContent(content string, params ...gview.Params) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// 解析模板文件,并返回模板内容
|
||||
// ParseTpl parses given template file <tpl> with given template variables <params>
|
||||
// and returns the parsed template content.
|
||||
func (r *Response) ParseTpl(tpl string, params ...gview.Params) (string, error) {
|
||||
if r.Server.config.View != nil {
|
||||
return r.Server.config.View.Parse(tpl, r.buildInVars(params...))
|
||||
}
|
||||
return gview.Instance().Parse(tpl, r.buildInVars(params...))
|
||||
return r.GetView().Parse(tpl, r.buildInVars(params...))
|
||||
}
|
||||
|
||||
// 解析并返回模板内容
|
||||
// ParseDefault parses the default template file with params.
|
||||
func (r *Response) ParseTplDefault(params ...gview.Params) (string, error) {
|
||||
return r.GetView().ParseDefault(r.buildInVars(params...))
|
||||
}
|
||||
|
||||
// ParseTplContent parses given template file <file> with given template parameters <params>
|
||||
// and returns the parsed template content.
|
||||
func (r *Response) ParseTplContent(content string, params ...gview.Params) (string, error) {
|
||||
if r.Server.config.View != nil {
|
||||
return r.Server.config.View.ParseContent(content, r.buildInVars(params...))
|
||||
}
|
||||
return gview.Instance().ParseContent(content, r.buildInVars(params...))
|
||||
return r.GetView().ParseContent(content, r.buildInVars(params...))
|
||||
}
|
||||
|
||||
// 内置变量/对象
|
||||
// buildInVars merges build-in variables into <params> and returns the new template variables.
|
||||
func (r *Response) buildInVars(params ...map[string]interface{}) map[string]interface{} {
|
||||
var vars map[string]interface{}
|
||||
if len(params) > 0 && params[0] != nil {
|
||||
|
@ -14,13 +14,13 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Custom ResponseWriter, which is used for controlling the output buffer.
|
||||
// ResponseWriter is the custom writer for http response.
|
||||
type ResponseWriter struct {
|
||||
Status int // HTTP status.
|
||||
writer http.ResponseWriter // The underlying ResponseWriter.
|
||||
buffer *bytes.Buffer // The output buffer.
|
||||
hijacked bool // Mark this request is hijacked or not.
|
||||
wroteHeader bool // Is header wrote, avoiding error: superfluous/multiple response.WriteHeader call.
|
||||
wroteHeader bool // Is header wrote or not, avoiding error: superfluous/multiple response.WriteHeader call.
|
||||
}
|
||||
|
||||
// RawWriter returns the underlying ResponseWriter.
|
||||
|
@ -48,9 +48,8 @@ type fileCacheItem struct {
|
||||
content string
|
||||
}
|
||||
|
||||
// ParseContent parses given template file <file>
|
||||
// with given template parameters <params> and function map <funcMap>
|
||||
// and returns the parsed string content.
|
||||
// Parse parses given template file <file> with given template variables <params>
|
||||
// and returns the parsed template content.
|
||||
func (view *View) Parse(file string, params ...Params) (result string, err error) {
|
||||
var tpl *template.Template
|
||||
// It caches the file, folder and its content to enhance performance.
|
||||
@ -143,8 +142,7 @@ func (view *View) ParseDefault(params ...Params) (result string, err error) {
|
||||
return view.Parse(view.defaultFile, params...)
|
||||
}
|
||||
|
||||
// ParseContent parses given template content <content>
|
||||
// with given template parameters <params> and function map <funcMap>
|
||||
// ParseContent parses given template content <content> with template variables <params>
|
||||
// and returns the parsed content in []byte.
|
||||
func (view *View) ParseContent(content string, params ...Params) (string, error) {
|
||||
err := (error)(nil)
|
||||
@ -201,7 +199,7 @@ func (view *View) ParseContent(content string, params ...Params) (string, error)
|
||||
|
||||
// getTemplate returns the template object associated with given template folder <path>.
|
||||
// It uses template cache to enhance performance, that is, it will return the same template object
|
||||
// with the same given <path>. It will also refresh the template cache
|
||||
// with the same given <path>. It will also automatically refresh the template cache
|
||||
// if the template files under <path> changes (recursively).
|
||||
func (view *View) getTemplate(path string, pattern string) (tpl *template.Template, err error) {
|
||||
r := templates.GetOrSetFuncLock(path, func() interface{} {
|
||||
@ -237,7 +235,7 @@ func (view *View) getTemplate(path string, pattern string) (tpl *template.Templa
|
||||
return
|
||||
}
|
||||
|
||||
// searchFile returns the found absolute path for <file>, and its template folder path.
|
||||
// searchFile returns the found absolute path for <file> and its template folder path.
|
||||
func (view *View) searchFile(file string) (path string, folder string, resource *gres.File, err error) {
|
||||
// Firstly checking the resource manager.
|
||||
if !gres.IsEmpty() {
|
||||
|
Loading…
Reference in New Issue
Block a user