diff --git a/main.go b/main.go index b88dc375..a51144e5 100644 --- a/main.go +++ b/main.go @@ -177,15 +177,6 @@ func (s *DB) QueryExpr() *expr { return Expr(scope.SQL, scope.SQLVars...) } -// SubQuery returns the query as sub query -func (s *DB) SubQuery() *expr { - scope := s.NewScope(s.Value) - scope.InstanceSet("skip_bindvar", true) - scope.prepareQuerySQL() - - return Expr(fmt.Sprintf("(%v)", scope.SQL), scope.SQLVars...) -} - // Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/crud.html#query func (s *DB) Where(query interface{}, args ...interface{}) *DB { return s.clone().search.Where(query, args...).db @@ -820,16 +811,17 @@ func (s *DB) EnableAfterScanCallback(typs ...interface{}) *DB { func (s *DB) EnabledAfterScanCallback(typs ...interface{}) (ok bool) { key := "gorm:disable_after_scan" - if v, ok := s.values[key]; !ok || v.(bool) { - for _, typ := range typs { - rType := indirectType(reflect.TypeOf(typ)) - v, ok = s.values[key + ":" + rType.PkgPath() + "." + rType.Name()] - if ok && !v.(bool) { - return false - } - } - return true + if v, ok := s.values[key]; ok { + return !v.(bool) } - return false + for _, typ := range typs { + rType := indirectType(reflect.TypeOf(typ)) + v, ok := s.values[key + ":" + rType.PkgPath() + "." + rType.Name()] + if ok && v.(bool) { + return false + } + } + + return true } diff --git a/scope.go b/scope.go index 6935219e..008f28b1 100644 --- a/scope.go +++ b/scope.go @@ -475,16 +475,18 @@ func (scope *Scope) quoteIfPossible(str string) string { // call after field method callbacks func (scope *Scope) afterScanCallback(scannerFields map[int]*Field, disableScanField map[int]bool) { - if !scope.HasError() { + if !scope.HasError() && scope.Value != nil { if scope.DB().EnabledAfterScanCallback(scope.Value) { scopeValue := reflect.ValueOf(scope) for index, field := range scannerFields { - // if calbacks enabled for field type + // if not is nill and if calbacks enabled for field type if StructFieldMethodCallbacks.EnabledFieldType(field.Field.Type()) { // not disabled on scan if _, ok := disableScanField[index]; !ok { - reflectValue := field.Field.Addr() - field.CallMethodCallback("AfterScan", reflectValue, scopeValue) + if !isNil(field.Field) { + reflectValue := field.Field.Addr() + field.CallMethodCallback("AfterScan", reflectValue, scopeValue) + } } } } diff --git a/scope_test.go b/scope_test.go index fa4c30fb..1a1e3621 100644 --- a/scope_test.go +++ b/scope_test.go @@ -127,20 +127,16 @@ func TestAfterFieldScanDisableCallback(t *testing.T) { DB := DB.DisableAfterScanCallback(typs...) var model2 WithFieldAfterScanCallback if err := DB.Where("id = ?", model.ID).First(&model2).Error; err != nil { - t.Errorf("%q: No error should happen when querying WithFieldAfterScanCallback with valuer, but got %v", len(typs), err) + t.Errorf("%v: No error should happen when querying WithFieldAfterScanCallback with valuer, but got %v", len(typs), err) } - dotest := func(i int, value string, field AfterScanFieldInterface) { + dotest := func(i int, field AfterScanFieldInterface) { if !field.CalledFieldIsNill() { - t.Errorf("%q: Expected Name%v.calledField is not nil", len(typs), i) - } - - if !field.CalledScopeIsNill() { - t.Errorf("%q: Expected Name%v.calledScope is not nil", len(typs), i) + t.Errorf("%v: Expected Name%v.calledField is nil", len(typs), i) } } - dotest(1, model.Name1.data, model2.Name1) + dotest(1, model2.Name1) } run() diff --git a/utils.go b/utils.go index 870f143d..355225b2 100644 --- a/utils.go +++ b/utils.go @@ -367,4 +367,15 @@ func checkOrPanic(err error) { if err != nil { panic(err) } +} + +// check if value is nil +func isNil(value reflect.Value) bool { + if value.Kind() != reflect.Ptr { + return false + } + if value.Pointer() == 0 { + return true + } + return false } \ No newline at end of file