You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							105 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							105 lines
						
					
					
						
							2.6 KiB
						
					
					
				
								package schema
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"reflect"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								func StructToSchema(instance any) *schema_pb.RecordType {
							 | 
						|
									myType := reflect.TypeOf(instance)
							 | 
						|
									if myType.Kind() != reflect.Struct {
							 | 
						|
										return nil
							 | 
						|
									}
							 | 
						|
									st := reflectTypeToSchemaType(myType)
							 | 
						|
									return st.GetRecordType()
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// CreateCombinedRecordType creates a combined RecordType that includes fields from both key and value schemas
							 | 
						|
								// Key fields are prefixed with "key_" to distinguish them from value fields
							 | 
						|
								func CreateCombinedRecordType(keyRecordType *schema_pb.RecordType, valueRecordType *schema_pb.RecordType) *schema_pb.RecordType {
							 | 
						|
									var combinedFields []*schema_pb.Field
							 | 
						|
								
							 | 
						|
									// Add key fields with "key_" prefix
							 | 
						|
									if keyRecordType != nil {
							 | 
						|
										for _, field := range keyRecordType.Fields {
							 | 
						|
											keyField := &schema_pb.Field{
							 | 
						|
												Name:       "key_" + field.Name,
							 | 
						|
												FieldIndex: field.FieldIndex, // Will be reindexed later
							 | 
						|
												Type:       field.Type,
							 | 
						|
												IsRepeated: field.IsRepeated,
							 | 
						|
												IsRequired: field.IsRequired,
							 | 
						|
											}
							 | 
						|
											combinedFields = append(combinedFields, keyField)
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// Add value fields (no prefix)
							 | 
						|
									if valueRecordType != nil {
							 | 
						|
										for _, field := range valueRecordType.Fields {
							 | 
						|
											combinedFields = append(combinedFields, field)
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// Reindex all fields to have sequential indices
							 | 
						|
									for i, field := range combinedFields {
							 | 
						|
										field.FieldIndex = int32(i)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return &schema_pb.RecordType{
							 | 
						|
										Fields: combinedFields,
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func reflectTypeToSchemaType(t reflect.Type) *schema_pb.Type {
							 | 
						|
									switch t.Kind() {
							 | 
						|
									case reflect.Bool:
							 | 
						|
										return TypeBoolean
							 | 
						|
									case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
							 | 
						|
										return TypeInt32
							 | 
						|
									case reflect.Int64:
							 | 
						|
										return TypeInt64
							 | 
						|
									case reflect.Float32:
							 | 
						|
										return TypeFloat
							 | 
						|
									case reflect.Float64:
							 | 
						|
										return TypeDouble
							 | 
						|
									case reflect.String:
							 | 
						|
										return TypeString
							 | 
						|
									case reflect.Slice:
							 | 
						|
										switch t.Elem().Kind() {
							 | 
						|
										case reflect.Uint8:
							 | 
						|
											return TypeBytes
							 | 
						|
										default:
							 | 
						|
											if st := reflectTypeToSchemaType(t.Elem()); st != nil {
							 | 
						|
												return &schema_pb.Type{
							 | 
						|
													Kind: &schema_pb.Type_ListType{
							 | 
						|
														ListType: &schema_pb.ListType{
							 | 
						|
															ElementType: st,
							 | 
						|
														},
							 | 
						|
													},
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									case reflect.Struct:
							 | 
						|
										recordType := &schema_pb.RecordType{}
							 | 
						|
										for i := 0; i < t.NumField(); i++ {
							 | 
						|
											field := t.Field(i)
							 | 
						|
											fieldType := field.Type
							 | 
						|
											fieldName := field.Name
							 | 
						|
											schemaField := reflectTypeToSchemaType(fieldType)
							 | 
						|
											if schemaField == nil {
							 | 
						|
												return nil
							 | 
						|
											}
							 | 
						|
											recordType.Fields = append(recordType.Fields, &schema_pb.Field{
							 | 
						|
												Name: fieldName,
							 | 
						|
												Type: schemaField,
							 | 
						|
											})
							 | 
						|
										}
							 | 
						|
										return &schema_pb.Type{
							 | 
						|
											Kind: &schema_pb.Type_RecordType{
							 | 
						|
												RecordType: recordType,
							 | 
						|
											},
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
									return nil
							 | 
						|
								}
							 |