Spaces:
				
			
			
	
			
			
		Sleeping
		
	
	
	
			
			
	
	
	
	
		
		
		Sleeping
		
	| // _ _ | |
| // __ _____ __ ___ ___ __ _| |_ ___ | |
| // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
| // \ V V / __/ (_| |\ V /| | (_| | || __/ | |
| // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
| // | |
| // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
| // | |
| // CONTACT: [email protected] | |
| // | |
| package schema | |
| import ( | |
| errors_ "errors" | |
| "fmt" | |
| "strings" | |
| "github.com/weaviate/weaviate/entities/models" | |
| ) | |
| type PropertyInterface interface { | |
| GetName() string | |
| GetNestedProperties() []*models.NestedProperty | |
| } | |
| // GetClassByName returns the class by its name | |
| func GetClassByName(s *models.Schema, className string) (*models.Class, error) { | |
| if s == nil { | |
| return nil, fmt.Errorf(ErrorNoSuchClass, className) | |
| } | |
| // For each class | |
| for _, class := range s.Classes { | |
| // Check if the name of the class is the given name, that's the class we need | |
| if class.Class == className { | |
| return class, nil | |
| } | |
| } | |
| return nil, fmt.Errorf(ErrorNoSuchClass, className) | |
| } | |
| // GetPropertyByName returns the class by its name | |
| func GetPropertyByName(c *models.Class, propName string) (*models.Property, error) { | |
| // For each class-property | |
| for _, prop := range c.Properties { | |
| // Check if the name of the property is the given name, that's the property we need | |
| if prop.Name == strings.Split(propName, ".")[0] { | |
| return prop, nil | |
| } | |
| } | |
| return nil, fmt.Errorf(ErrorNoSuchProperty, propName, c.Class) | |
| } | |
| // GetPropertyDataType checks whether the given string is a valid data type | |
| func GetPropertyDataType(class *models.Class, propertyName string) (*DataType, error) { | |
| // Get the class-property | |
| prop, err := GetPropertyByName(class, propertyName) | |
| if err != nil { | |
| return nil, err | |
| } | |
| // Init the return value | |
| var returnDataType DataType | |
| // For each data type | |
| for _, dataType := range prop.DataType { | |
| if len(dataType) == 0 { | |
| return nil, fmt.Errorf("invalid-dataType") | |
| } | |
| // Get the first letter to see if it is a capital | |
| firstLetter := string(dataType[0]) | |
| if strings.ToUpper(firstLetter) == firstLetter { | |
| returnDataType = DataTypeCRef | |
| } else { | |
| // Get the value-data type (non-cref), return error if there is one, otherwise assign it to return data type | |
| valueDataType, err := GetValueDataTypeFromString(dataType) | |
| if err != nil { | |
| return nil, err | |
| } | |
| returnDataType = *valueDataType | |
| } | |
| } | |
| return &returnDataType, nil | |
| } | |
| func GetNestedPropertyByName[P PropertyInterface](p P, propName string) (*models.NestedProperty, error) { | |
| // For each nested-property | |
| for _, prop := range p.GetNestedProperties() { | |
| // Check if the name of the property is the given name, that's the property we need | |
| if prop.Name == strings.Split(propName, ".")[0] { | |
| return prop, nil | |
| } | |
| } | |
| return nil, fmt.Errorf(ErrorNoSuchProperty, propName, p.GetName()) | |
| } | |
| func GetNestedPropertyDataType[P PropertyInterface](p P, propertyName string) (*DataType, error) { | |
| // Get the class-property | |
| prop, err := GetNestedPropertyByName(p, propertyName) | |
| if err != nil { | |
| return nil, err | |
| } | |
| // Init the return value | |
| var returnDataType DataType | |
| // For each data type | |
| for _, dataType := range prop.DataType { | |
| if len(dataType) == 0 { | |
| return nil, fmt.Errorf("invalid-dataType") | |
| } | |
| // Get the first letter to see if it is a capital | |
| firstLetter := string(dataType[0]) | |
| if strings.ToUpper(firstLetter) == firstLetter { | |
| returnDataType = DataTypeCRef | |
| } else { | |
| // Get the value-data type (non-cref), return error if there is one, otherwise assign it to return data type | |
| valueDataType, err := GetValueDataTypeFromString(dataType) | |
| if err != nil { | |
| return nil, err | |
| } | |
| returnDataType = *valueDataType | |
| } | |
| } | |
| return &returnDataType, nil | |
| } | |
| // GetValueDataTypeFromString checks whether the given string is a valid data type | |
| func GetValueDataTypeFromString(dt string) (*DataType, error) { | |
| var returnDataType DataType | |
| if IsValidValueDataType(dt) { | |
| returnDataType = DataType(dt) | |
| } else { | |
| return nil, errors_.New(ErrorNoSuchDatatype) | |
| } | |
| return &returnDataType, nil | |
| } | |
| // IsValidValueDataType checks whether the given string is a valid data type | |
| func IsValidValueDataType(dt string) bool { | |
| switch dt { | |
| case | |
| string(DataTypeString), | |
| string(DataTypeText), | |
| string(DataTypeInt), | |
| string(DataTypeNumber), | |
| string(DataTypeBoolean), | |
| string(DataTypeDate), | |
| string(DataTypeGeoCoordinates), | |
| string(DataTypePhoneNumber), | |
| string(DataTypeBlob), | |
| string(DataTypeUUID), | |
| string(DataTypeUUIDArray), | |
| string(DataTypeStringArray), | |
| string(DataTypeTextArray), | |
| string(DataTypeIntArray), | |
| string(DataTypeNumberArray), | |
| string(DataTypeBooleanArray), | |
| string(DataTypeDateArray), | |
| string(DataTypeObject), | |
| string(DataTypeObjectArray): | |
| return true | |
| } | |
| return false | |
| } | |
| func IsRefDataType(dt []string) bool { | |
| firstLetter := string(dt[0][0]) | |
| return strings.ToUpper(firstLetter) == firstLetter | |
| } | |
| func IsBlobDataType(dt []string) bool { | |
| for i := range dt { | |
| if dt[i] == string(DataTypeBlob) { | |
| return true | |
| } | |
| } | |
| return false | |
| } | |
| func IsArrayDataType(dt []string) bool { | |
| for i := range dt { | |
| switch DataType(dt[i]) { | |
| case DataTypeStringArray, DataTypeTextArray, DataTypeIntArray, | |
| DataTypeNumberArray, DataTypeBooleanArray, DataTypeDateArray, | |
| DataTypeUUIDArray: | |
| return true | |
| default: | |
| // move to the next loop | |
| } | |
| } | |
| return false | |
| } | |