增加websocket支持
This commit is contained in:
		
							
								
								
									
										99
									
								
								vendor/gorm.io/gorm/callbacks/preload.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										99
									
								
								vendor/gorm.io/gorm/callbacks/preload.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,7 +3,6 @@ package callbacks | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
|  | ||||
| 	"gorm.io/gorm" | ||||
| @@ -75,7 +74,7 @@ func embeddedValues(embeddedRelations *schema.Relationships) []string { | ||||
| 	names := make([]string, 0, len(embeddedRelations.Relations)+len(embeddedRelations.EmbeddedRelations)) | ||||
| 	for _, relation := range embeddedRelations.Relations { | ||||
| 		// skip first struct name | ||||
| 		names = append(names, strings.Join(relation.Field.EmbeddedBindNames[1:], ".")) | ||||
| 		names = append(names, strings.Join(relation.Field.BindNames[1:], ".")) | ||||
| 	} | ||||
| 	for _, relations := range embeddedRelations.EmbeddedRelations { | ||||
| 		names = append(names, embeddedValues(relations)...) | ||||
| @@ -83,103 +82,27 @@ func embeddedValues(embeddedRelations *schema.Relationships) []string { | ||||
| 	return names | ||||
| } | ||||
|  | ||||
| // preloadEntryPoint enters layer by layer. It will call real preload if it finds the right entry point. | ||||
| // If the current relationship is embedded or joined, current query will be ignored. | ||||
| // | ||||
| //nolint:cyclop | ||||
| func preloadEntryPoint(db *gorm.DB, joins []string, relationships *schema.Relationships, preloads map[string][]interface{}, associationsConds []interface{}) error { | ||||
| 	preloadMap := parsePreloadMap(db.Statement.Schema, preloads) | ||||
|  | ||||
| 	// avoid random traversal of the map | ||||
| 	preloadNames := make([]string, 0, len(preloadMap)) | ||||
| 	for key := range preloadMap { | ||||
| 		preloadNames = append(preloadNames, key) | ||||
| func preloadEmbedded(tx *gorm.DB, relationships *schema.Relationships, s *schema.Schema, preloads map[string][]interface{}, as []interface{}) error { | ||||
| 	if relationships == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	sort.Strings(preloadNames) | ||||
|  | ||||
| 	isJoined := func(name string) (joined bool, nestedJoins []string) { | ||||
| 		for _, join := range joins { | ||||
| 			if _, ok := relationships.Relations[join]; ok && name == join { | ||||
| 				joined = true | ||||
| 				continue | ||||
| 			} | ||||
| 			joinNames := strings.SplitN(join, ".", 2) | ||||
| 			if len(joinNames) == 2 { | ||||
| 				if _, ok := relationships.Relations[joinNames[0]]; ok && name == joinNames[0] { | ||||
| 					joined = true | ||||
| 					nestedJoins = append(nestedJoins, joinNames[1]) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return joined, nestedJoins | ||||
| 	} | ||||
|  | ||||
| 	for _, name := range preloadNames { | ||||
| 		if relations := relationships.EmbeddedRelations[name]; relations != nil { | ||||
| 			if err := preloadEntryPoint(db, joins, relations, preloadMap[name], associationsConds); err != nil { | ||||
| 	preloadMap := parsePreloadMap(s, preloads) | ||||
| 	for name := range preloadMap { | ||||
| 		if embeddedRelations := relationships.EmbeddedRelations[name]; embeddedRelations != nil { | ||||
| 			if err := preloadEmbedded(tx, embeddedRelations, s, preloadMap[name], as); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else if rel := relationships.Relations[name]; rel != nil { | ||||
| 			if joined, nestedJoins := isJoined(name); joined { | ||||
| 				switch rv := db.Statement.ReflectValue; rv.Kind() { | ||||
| 				case reflect.Slice, reflect.Array: | ||||
| 					if rv.Len() > 0 { | ||||
| 						reflectValue := rel.FieldSchema.MakeSlice().Elem() | ||||
| 						reflectValue.SetLen(rv.Len()) | ||||
| 						for i := 0; i < rv.Len(); i++ { | ||||
| 							frv := rel.Field.ReflectValueOf(db.Statement.Context, rv.Index(i)) | ||||
| 							if frv.Kind() != reflect.Ptr { | ||||
| 								reflectValue.Index(i).Set(frv.Addr()) | ||||
| 							} else { | ||||
| 								reflectValue.Index(i).Set(frv) | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
| 						tx := preloadDB(db, reflectValue, reflectValue.Interface()) | ||||
| 						if err := preloadEntryPoint(tx, nestedJoins, &tx.Statement.Schema.Relationships, preloadMap[name], associationsConds); err != nil { | ||||
| 							return err | ||||
| 						} | ||||
| 					} | ||||
| 				case reflect.Struct: | ||||
| 					reflectValue := rel.Field.ReflectValueOf(db.Statement.Context, rv) | ||||
| 					tx := preloadDB(db, reflectValue, reflectValue.Interface()) | ||||
| 					if err := preloadEntryPoint(tx, nestedJoins, &tx.Statement.Schema.Relationships, preloadMap[name], associationsConds); err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 				default: | ||||
| 					return gorm.ErrInvalidData | ||||
| 				} | ||||
| 			} else { | ||||
| 				tx := db.Table("").Session(&gorm.Session{Context: db.Statement.Context, SkipHooks: db.Statement.SkipHooks}) | ||||
| 				tx.Statement.ReflectValue = db.Statement.ReflectValue | ||||
| 				tx.Statement.Unscoped = db.Statement.Unscoped | ||||
| 				if err := preload(tx, rel, append(preloads[name], associationsConds...), preloadMap[name]); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			if err := preload(tx, rel, append(preloads[name], as), preloadMap[name]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			return fmt.Errorf("%s: %w for schema %s", name, gorm.ErrUnsupportedRelation, db.Statement.Schema.Name) | ||||
| 			return fmt.Errorf("%s: %w (embedded) for schema %s", name, gorm.ErrUnsupportedRelation, s.Name) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func preloadDB(db *gorm.DB, reflectValue reflect.Value, dest interface{}) *gorm.DB { | ||||
| 	tx := db.Session(&gorm.Session{Context: db.Statement.Context, NewDB: true, SkipHooks: db.Statement.SkipHooks, Initialized: true}) | ||||
| 	db.Statement.Settings.Range(func(k, v interface{}) bool { | ||||
| 		tx.Statement.Settings.Store(k, v) | ||||
| 		return true | ||||
| 	}) | ||||
|  | ||||
| 	if err := tx.Statement.Parse(dest); err != nil { | ||||
| 		tx.AddError(err) | ||||
| 		return tx | ||||
| 	} | ||||
| 	tx.Statement.ReflectValue = reflectValue | ||||
| 	tx.Statement.Unscoped = db.Statement.Unscoped | ||||
| 	return tx | ||||
| } | ||||
|  | ||||
| func preload(tx *gorm.DB, rel *schema.Relationship, conds []interface{}, preloads map[string][]interface{}) error { | ||||
| 	var ( | ||||
| 		reflectValue     = tx.Statement.ReflectValue | ||||
|   | ||||
		Reference in New Issue
	
	Block a user