diff --git a/callback.go b/callback.go index 56b2064a..1f0e3c79 100644 --- a/callback.go +++ b/callback.go @@ -3,7 +3,7 @@ package gorm import "fmt" // DefaultCallback default callbacks defined by gorm -var DefaultCallback = &Callback{} +var DefaultCallback = &Callback{logger: nopLogger{}} // Callback is a struct that contains all CRUD callbacks // 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 { - // 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.logger.Print("info", fmt.Sprintf("[info] registering callback `%v` from %v", callbackName, fileWithLineNum())) cp.name = callbackName cp.processor = &callback cp.parent.processors = append(cp.parent.processors, cp) diff --git a/callbacks_test.go b/callbacks_test.go index c1a1d5e4..bebd0e38 100644 --- a/callbacks_test.go +++ b/callbacks_test.go @@ -217,3 +217,33 @@ func TestGetCallback(t *testing.T) { 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) + } +} diff --git a/go.mod b/go.mod index 2d2fec37..4d6eb7fa 100644 --- a/go.mod +++ b/go.mod @@ -9,5 +9,5 @@ require ( github.com/jinzhu/inflection v1.0.0 github.com/jinzhu/now v1.0.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 ) diff --git a/go.sum b/go.sum index c43559bf..a9ae14d5 100644 --- a/go.sum +++ b/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/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.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/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= diff --git a/logger.go b/logger.go index a42f2727..88e167dd 100644 --- a/logger.go +++ b/logger.go @@ -39,6 +39,15 @@ var LogFormatter = func(values ...interface{}) (messages []interface{}) { 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" { // duration 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{}) { logger.Println(LogFormatter(values...)...) } + +type nopLogger struct{} + +func (nopLogger) Print(values ...interface{}) {} diff --git a/main.go b/main.go index 48d22c85..24fd8382 100644 --- a/main.go +++ b/main.go @@ -528,12 +528,12 @@ func (s *DB) Debug() *DB { // Transaction start a transaction as a block, // return error will rollback, otherwise to commit. func (s *DB) Transaction(fc func(tx *DB) error) (err error) { + panicked := true tx := s.Begin() defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("%s", r) + // Make sure to rollback when panic, Block error or Commit error + if panicked || err != nil { tx.Rollback() - return } }() @@ -543,10 +543,7 @@ func (s *DB) Transaction(fc func(tx *DB) error) (err error) { err = tx.Commit().Error } - // Makesure rollback when Block error or Commit error - if err != nil { - tx.Rollback() - } + panicked = false return } diff --git a/main_test.go b/main_test.go index 134672b7..98ea4694 100644 --- a/main_test.go +++ b/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) { // rollback err := DB.Transaction(func(tx *gorm.DB) error { @@ -511,17 +520,19 @@ func TestTransactionWithBlock(t *testing.T) { } // panic will rollback - DB.Transaction(func(tx *gorm.DB) error { - u3 := User{Name: "transcation-3"} - if err := tx.Save(&u3).Error; err != nil { - t.Errorf("No error should raise") - } + assertPanic(t, func() { + DB.Transaction(func(tx *gorm.DB) error { + u3 := User{Name: "transcation-3"} + 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 { - t.Errorf("Should find saved record") - } + if err := tx.First(&User{}, "name = ?", "transcation-3").Error; err != nil { + t.Errorf("Should find saved record") + } - panic("force panic") + panic("force panic") + }) }) if err := DB.First(&User{}, "name = ?", "transcation").Error; err == nil {