github.com/weaviate/weaviate@v1.24.6/entities/schema/backward_compat.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package schema 13 14 import ( 15 errors_ "errors" 16 "fmt" 17 "strings" 18 19 "github.com/weaviate/weaviate/entities/models" 20 ) 21 22 type PropertyInterface interface { 23 GetName() string 24 GetNestedProperties() []*models.NestedProperty 25 } 26 27 // GetClassByName returns the class by its name 28 func GetClassByName(s *models.Schema, className string) (*models.Class, error) { 29 if s == nil { 30 return nil, fmt.Errorf(ErrorNoSuchClass, className) 31 } 32 // For each class 33 for _, class := range s.Classes { 34 // Check if the name of the class is the given name, that's the class we need 35 if class.Class == className { 36 return class, nil 37 } 38 } 39 40 return nil, fmt.Errorf(ErrorNoSuchClass, className) 41 } 42 43 // GetPropertyByName returns the class by its name 44 func GetPropertyByName(c *models.Class, propName string) (*models.Property, error) { 45 // For each class-property 46 for _, prop := range c.Properties { 47 // Check if the name of the property is the given name, that's the property we need 48 if prop.Name == strings.Split(propName, ".")[0] { 49 return prop, nil 50 } 51 } 52 53 return nil, fmt.Errorf(ErrorNoSuchProperty, propName, c.Class) 54 } 55 56 // GetPropertyDataType checks whether the given string is a valid data type 57 func GetPropertyDataType(class *models.Class, propertyName string) (*DataType, error) { 58 // Get the class-property 59 prop, err := GetPropertyByName(class, propertyName) 60 if err != nil { 61 return nil, err 62 } 63 64 // Init the return value 65 var returnDataType DataType 66 67 // For each data type 68 for _, dataType := range prop.DataType { 69 if len(dataType) == 0 { 70 return nil, fmt.Errorf("invalid-dataType") 71 } 72 // Get the first letter to see if it is a capital 73 firstLetter := string(dataType[0]) 74 if strings.ToUpper(firstLetter) == firstLetter { 75 returnDataType = DataTypeCRef 76 } else { 77 // Get the value-data type (non-cref), return error if there is one, otherwise assign it to return data type 78 valueDataType, err := GetValueDataTypeFromString(dataType) 79 if err != nil { 80 return nil, err 81 } 82 returnDataType = *valueDataType 83 } 84 } 85 return &returnDataType, nil 86 } 87 88 func GetNestedPropertyByName[P PropertyInterface](p P, propName string) (*models.NestedProperty, error) { 89 // For each nested-property 90 for _, prop := range p.GetNestedProperties() { 91 // Check if the name of the property is the given name, that's the property we need 92 if prop.Name == strings.Split(propName, ".")[0] { 93 return prop, nil 94 } 95 } 96 97 return nil, fmt.Errorf(ErrorNoSuchProperty, propName, p.GetName()) 98 } 99 100 func GetNestedPropertyDataType[P PropertyInterface](p P, propertyName string) (*DataType, error) { 101 // Get the class-property 102 prop, err := GetNestedPropertyByName(p, propertyName) 103 if err != nil { 104 return nil, err 105 } 106 107 // Init the return value 108 var returnDataType DataType 109 110 // For each data type 111 for _, dataType := range prop.DataType { 112 if len(dataType) == 0 { 113 return nil, fmt.Errorf("invalid-dataType") 114 } 115 // Get the first letter to see if it is a capital 116 firstLetter := string(dataType[0]) 117 if strings.ToUpper(firstLetter) == firstLetter { 118 returnDataType = DataTypeCRef 119 } else { 120 // Get the value-data type (non-cref), return error if there is one, otherwise assign it to return data type 121 valueDataType, err := GetValueDataTypeFromString(dataType) 122 if err != nil { 123 return nil, err 124 } 125 returnDataType = *valueDataType 126 } 127 } 128 return &returnDataType, nil 129 } 130 131 // GetValueDataTypeFromString checks whether the given string is a valid data type 132 func GetValueDataTypeFromString(dt string) (*DataType, error) { 133 var returnDataType DataType 134 135 if IsValidValueDataType(dt) { 136 returnDataType = DataType(dt) 137 } else { 138 return nil, errors_.New(ErrorNoSuchDatatype) 139 } 140 141 return &returnDataType, nil 142 } 143 144 // IsValidValueDataType checks whether the given string is a valid data type 145 func IsValidValueDataType(dt string) bool { 146 switch dt { 147 case 148 string(DataTypeString), 149 string(DataTypeText), 150 string(DataTypeInt), 151 string(DataTypeNumber), 152 string(DataTypeBoolean), 153 string(DataTypeDate), 154 string(DataTypeGeoCoordinates), 155 string(DataTypePhoneNumber), 156 string(DataTypeBlob), 157 string(DataTypeUUID), 158 string(DataTypeUUIDArray), 159 string(DataTypeStringArray), 160 string(DataTypeTextArray), 161 string(DataTypeIntArray), 162 string(DataTypeNumberArray), 163 string(DataTypeBooleanArray), 164 string(DataTypeDateArray), 165 string(DataTypeObject), 166 string(DataTypeObjectArray): 167 return true 168 } 169 return false 170 } 171 172 func IsRefDataType(dt []string) bool { 173 firstLetter := string(dt[0][0]) 174 return strings.ToUpper(firstLetter) == firstLetter 175 } 176 177 func IsBlobDataType(dt []string) bool { 178 for i := range dt { 179 if dt[i] == string(DataTypeBlob) { 180 return true 181 } 182 } 183 return false 184 } 185 186 func IsArrayDataType(dt []string) bool { 187 for i := range dt { 188 switch DataType(dt[i]) { 189 case DataTypeStringArray, DataTypeTextArray, DataTypeIntArray, 190 DataTypeNumberArray, DataTypeBooleanArray, DataTypeDateArray, 191 DataTypeUUIDArray: 192 return true 193 default: 194 // move to the next loop 195 } 196 } 197 return false 198 }