X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=blobdiff_plain;f=vendor%2Fgithub.com%2Fjinzhu%2Fgorm%2Fcallback_query.go;fp=vendor%2Fgithub.com%2Fjinzhu%2Fgorm%2Fcallback_query.go;h=593e5d304e47cb0637f4b078616b32ce7b23bb41;hp=0000000000000000000000000000000000000000;hb=54373c1a3efe0e373ec1605840a4363e4b246c46;hpb=ee01d543fdfe1fd0a4d548965c66f7923ea7b062 diff --git a/vendor/github.com/jinzhu/gorm/callback_query.go b/vendor/github.com/jinzhu/gorm/callback_query.go new file mode 100755 index 00000000..593e5d30 --- /dev/null +++ b/vendor/github.com/jinzhu/gorm/callback_query.go @@ -0,0 +1,104 @@ +package gorm + +import ( + "errors" + "fmt" + "reflect" +) + +// Define callbacks for querying +func init() { + DefaultCallback.Query().Register("gorm:query", queryCallback) + DefaultCallback.Query().Register("gorm:preload", preloadCallback) + DefaultCallback.Query().Register("gorm:after_query", afterQueryCallback) +} + +// queryCallback used to query data from database +func queryCallback(scope *Scope) { + if _, skip := scope.InstanceGet("gorm:skip_query_callback"); skip { + return + } + + //we are only preloading relations, dont touch base model + if _, skip := scope.InstanceGet("gorm:only_preload"); skip { + return + } + + defer scope.trace(NowFunc()) + + var ( + isSlice, isPtr bool + resultType reflect.Type + results = scope.IndirectValue() + ) + + if orderBy, ok := scope.Get("gorm:order_by_primary_key"); ok { + if primaryField := scope.PrimaryField(); primaryField != nil { + scope.Search.Order(fmt.Sprintf("%v.%v %v", scope.QuotedTableName(), scope.Quote(primaryField.DBName), orderBy)) + } + } + + if value, ok := scope.Get("gorm:query_destination"); ok { + results = indirect(reflect.ValueOf(value)) + } + + if kind := results.Kind(); kind == reflect.Slice { + isSlice = true + resultType = results.Type().Elem() + results.Set(reflect.MakeSlice(results.Type(), 0, 0)) + + if resultType.Kind() == reflect.Ptr { + isPtr = true + resultType = resultType.Elem() + } + } else if kind != reflect.Struct { + scope.Err(errors.New("unsupported destination, should be slice or struct")) + return + } + + scope.prepareQuerySQL() + + if !scope.HasError() { + scope.db.RowsAffected = 0 + if str, ok := scope.Get("gorm:query_option"); ok { + scope.SQL += addExtraSpaceIfExist(fmt.Sprint(str)) + } + + if rows, err := scope.SQLDB().Query(scope.SQL, scope.SQLVars...); scope.Err(err) == nil { + defer rows.Close() + + columns, _ := rows.Columns() + for rows.Next() { + scope.db.RowsAffected++ + + elem := results + if isSlice { + elem = reflect.New(resultType).Elem() + } + + scope.scan(rows, columns, scope.New(elem.Addr().Interface()).Fields()) + + if isSlice { + if isPtr { + results.Set(reflect.Append(results, elem.Addr())) + } else { + results.Set(reflect.Append(results, elem)) + } + } + } + + if err := rows.Err(); err != nil { + scope.Err(err) + } else if scope.db.RowsAffected == 0 && !isSlice { + scope.Err(ErrRecordNotFound) + } + } + } +} + +// afterQueryCallback will invoke `AfterFind` method after querying +func afterQueryCallback(scope *Scope) { + if !scope.HasError() { + scope.CallMethod("AfterFind") + } +}