forked from mirror/gorm
Merge branch 'master' into add-limit-offset-parse-error
This commit is contained in:
commit
0f387db5b8
|
@ -3,7 +3,7 @@ package gorm
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// DefaultCallback default callbacks defined by gorm
|
// DefaultCallback default callbacks defined by gorm
|
||||||
var DefaultCallback = &Callback{}
|
var DefaultCallback = &Callback{logger: nopLogger{}}
|
||||||
|
|
||||||
// Callback is a struct that contains all CRUD callbacks
|
// Callback is a struct that contains all CRUD callbacks
|
||||||
// Field `creates` contains callbacks will be call when creating object
|
// Field `creates` contains callbacks will be call when creating object
|
||||||
|
@ -101,12 +101,7 @@ func (cp *CallbackProcessor) Register(callbackName string, callback func(scope *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cp.logger != nil {
|
cp.logger.Print("info", fmt.Sprintf("[info] registering callback `%v` from %v", callbackName, fileWithLineNum()))
|
||||||
// note cp.logger will be nil during the default gorm callback registrations
|
|
||||||
// as they occur within init() blocks. However, any user-registered callbacks
|
|
||||||
// will happen after cp.logger exists (as the default logger or user-specified).
|
|
||||||
cp.logger.Print("info", fmt.Sprintf("[info] registering callback `%v` from %v", callbackName, fileWithLineNum()))
|
|
||||||
}
|
|
||||||
cp.name = callbackName
|
cp.name = callbackName
|
||||||
cp.processor = &callback
|
cp.processor = &callback
|
||||||
cp.parent.processors = append(cp.parent.processors, cp)
|
cp.parent.processors = append(cp.parent.processors, cp)
|
||||||
|
|
|
@ -217,3 +217,33 @@ func TestGetCallback(t *testing.T) {
|
||||||
t.Errorf("`gorm:test_callback_value` should be `3, true` but `%v, %v`", v, ok)
|
t.Errorf("`gorm:test_callback_value` should be `3, true` but `%v, %v`", v, ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUseDefaultCallback(t *testing.T) {
|
||||||
|
createCallbackName := "gorm:test_use_default_callback_for_create"
|
||||||
|
gorm.DefaultCallback.Create().Register(createCallbackName, func(*gorm.Scope) {
|
||||||
|
// nop
|
||||||
|
})
|
||||||
|
if gorm.DefaultCallback.Create().Get(createCallbackName) == nil {
|
||||||
|
t.Errorf("`%s` expected non-nil, but got nil", createCallbackName)
|
||||||
|
}
|
||||||
|
gorm.DefaultCallback.Create().Remove(createCallbackName)
|
||||||
|
if gorm.DefaultCallback.Create().Get(createCallbackName) != nil {
|
||||||
|
t.Errorf("`%s` expected nil, but got non-nil", createCallbackName)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCallbackName := "gorm:test_use_default_callback_for_update"
|
||||||
|
scopeValueName := "gorm:test_use_default_callback_for_update_value"
|
||||||
|
gorm.DefaultCallback.Update().Register(updateCallbackName, func(scope *gorm.Scope) {
|
||||||
|
scope.Set(scopeValueName, 1)
|
||||||
|
})
|
||||||
|
gorm.DefaultCallback.Update().Replace(updateCallbackName, func(scope *gorm.Scope) {
|
||||||
|
scope.Set(scopeValueName, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
scope := DB.NewScope(nil)
|
||||||
|
callback := gorm.DefaultCallback.Update().Get(updateCallbackName)
|
||||||
|
callback(scope)
|
||||||
|
if v, ok := scope.Get(scopeValueName); !ok || v != 2 {
|
||||||
|
t.Errorf("`%s` should be `2, true` but `%v, %v`", scopeValueName, v, ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -9,5 +9,5 @@ require (
|
||||||
github.com/jinzhu/inflection v1.0.0
|
github.com/jinzhu/inflection v1.0.0
|
||||||
github.com/jinzhu/now v1.0.1
|
github.com/jinzhu/now v1.0.1
|
||||||
github.com/lib/pq v1.1.1
|
github.com/lib/pq v1.1.1
|
||||||
github.com/mattn/go-sqlite3 v1.11.0
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible
|
||||||
)
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -54,6 +54,10 @@ github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
||||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/Do=
|
||||||
|
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
|
13
logger.go
13
logger.go
|
@ -39,6 +39,15 @@ var LogFormatter = func(values ...interface{}) (messages []interface{}) {
|
||||||
|
|
||||||
messages = []interface{}{source, currentTime}
|
messages = []interface{}{source, currentTime}
|
||||||
|
|
||||||
|
if len(values) == 2 {
|
||||||
|
//remove the line break
|
||||||
|
currentTime = currentTime[1:]
|
||||||
|
//remove the brackets
|
||||||
|
source = fmt.Sprintf("\033[35m%v\033[0m", values[1])
|
||||||
|
|
||||||
|
messages = []interface{}{currentTime, source}
|
||||||
|
}
|
||||||
|
|
||||||
if level == "sql" {
|
if level == "sql" {
|
||||||
// duration
|
// duration
|
||||||
messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0))
|
messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0))
|
||||||
|
@ -126,3 +135,7 @@ type Logger struct {
|
||||||
func (logger Logger) Print(values ...interface{}) {
|
func (logger Logger) Print(values ...interface{}) {
|
||||||
logger.Println(LogFormatter(values...)...)
|
logger.Println(LogFormatter(values...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type nopLogger struct{}
|
||||||
|
|
||||||
|
func (nopLogger) Print(values ...interface{}) {}
|
||||||
|
|
11
main.go
11
main.go
|
@ -528,12 +528,12 @@ func (s *DB) Debug() *DB {
|
||||||
// Transaction start a transaction as a block,
|
// Transaction start a transaction as a block,
|
||||||
// return error will rollback, otherwise to commit.
|
// return error will rollback, otherwise to commit.
|
||||||
func (s *DB) Transaction(fc func(tx *DB) error) (err error) {
|
func (s *DB) Transaction(fc func(tx *DB) error) (err error) {
|
||||||
|
panicked := true
|
||||||
tx := s.Begin()
|
tx := s.Begin()
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
// Make sure to rollback when panic, Block error or Commit error
|
||||||
err = fmt.Errorf("%s", r)
|
if panicked || err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -543,10 +543,7 @@ func (s *DB) Transaction(fc func(tx *DB) error) (err error) {
|
||||||
err = tx.Commit().Error
|
err = tx.Commit().Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makesure rollback when Block error or Commit error
|
panicked = false
|
||||||
if err != nil {
|
|
||||||
tx.Rollback()
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
main_test.go
29
main_test.go
|
@ -470,6 +470,15 @@ func TestTransaction(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertPanic(t *testing.T, f func()) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r == nil {
|
||||||
|
t.Errorf("The code did not panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
func TestTransactionWithBlock(t *testing.T) {
|
func TestTransactionWithBlock(t *testing.T) {
|
||||||
// rollback
|
// rollback
|
||||||
err := DB.Transaction(func(tx *gorm.DB) error {
|
err := DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
@ -511,17 +520,19 @@ func TestTransactionWithBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// panic will rollback
|
// panic will rollback
|
||||||
DB.Transaction(func(tx *gorm.DB) error {
|
assertPanic(t, func() {
|
||||||
u3 := User{Name: "transcation-3"}
|
DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if err := tx.Save(&u3).Error; err != nil {
|
u3 := User{Name: "transcation-3"}
|
||||||
t.Errorf("No error should raise")
|
if err := tx.Save(&u3).Error; err != nil {
|
||||||
}
|
t.Errorf("No error should raise")
|
||||||
|
}
|
||||||
|
|
||||||
if err := tx.First(&User{}, "name = ?", "transcation-3").Error; err != nil {
|
if err := tx.First(&User{}, "name = ?", "transcation-3").Error; err != nil {
|
||||||
t.Errorf("Should find saved record")
|
t.Errorf("Should find saved record")
|
||||||
}
|
}
|
||||||
|
|
||||||
panic("force panic")
|
panic("force panic")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := DB.First(&User{}, "name = ?", "transcation").Error; err == nil {
|
if err := DB.First(&User{}, "name = ?", "transcation").Error; err == nil {
|
||||||
|
|
Loading…
Reference in New Issue