github.com/weaviate/weaviate@v1.24.6/entities/schema/validation.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 "fmt" 16 "regexp" 17 ) 18 19 var ( 20 validateClassNameRegex *regexp.Regexp 21 validatePropertyNameRegex *regexp.Regexp 22 validateNestedPropertyNameRegex *regexp.Regexp 23 reservedPropertyNames []string 24 ) 25 26 const ( 27 // Restricted by max length allowed for dir name (255 chars) 28 // As dir containing class data is named after class, 255 chars are allowed 29 classNameMaxLength = 255 30 ClassNameRegexCore = `[A-Z][_0-9A-Za-z]{0,254}` 31 ShardNameRegexCore = `[A-Za-z0-9\-\_]{1,64}` 32 // Restricted by max length allowed for dir name (255 chars) 33 // Property name is used to build dir names of various purposes containing property 34 // related data. Among them might be (depending on the settings): 35 // - geo.{property_name}.hnsw.commitlog.d 36 // - property_{property_name}__meta_count 37 // - property_{property_name}_propertyLength 38 // Last one seems to add the most additional characters (24) to property name, 39 // therefore poperty max lentgh should not exceed 255 - 24 = 231 chars. 40 propertyNameMaxLength = 231 41 PropertyNameRegex = `[_A-Za-z][_0-9A-Za-z]{0,230}` 42 // Nested properties names are not used to build directory names (yet), 43 // no max length restriction is imposed 44 NestedPropertyNameRegex = `[_A-Za-z][_0-9A-Za-z]*` 45 // Target vector names must be GraphQL compliant names no longer then 230 characters 46 TargetVectorNameMaxLength = 230 47 TargetVectorNameRegex = `[_A-Za-z][_0-9A-Za-z]{0,229}` 48 ) 49 50 func init() { 51 validateClassNameRegex = regexp.MustCompile(`^` + ClassNameRegexCore + `$`) 52 validatePropertyNameRegex = regexp.MustCompile(`^` + PropertyNameRegex + `$`) 53 validateNestedPropertyNameRegex = regexp.MustCompile(`^` + NestedPropertyNameRegex + `$`) 54 reservedPropertyNames = []string{"_additional", "_id", "id"} 55 } 56 57 // ValidateClassName validates that this string is a valid class name (format wise) 58 func ValidateClassName(name string) (ClassName, error) { 59 if len(name) > classNameMaxLength { 60 return "", fmt.Errorf("'%s' is not a valid class name. Name should not be longer than %d characters.", 61 name, classNameMaxLength) 62 } 63 if !validateClassNameRegex.MatchString(name) { 64 return "", fmt.Errorf("'%s' is not a valid class name", name) 65 } 66 return ClassName(name), nil 67 } 68 69 // ValidatePropertyName validates that this string is a valid property name 70 func ValidatePropertyName(name string) (PropertyName, error) { 71 if len(name) > propertyNameMaxLength { 72 return "", fmt.Errorf("'%s' is not a valid property name. Name should not be longer than %d characters.", 73 name, propertyNameMaxLength) 74 } 75 if !validatePropertyNameRegex.MatchString(name) { 76 return "", fmt.Errorf("'%s' is not a valid property name. "+ 77 "Property names in Weaviate are restricted to valid GraphQL names, "+ 78 "which must be “/%s/”.", name, PropertyNameRegex) 79 } 80 return PropertyName(name), nil 81 } 82 83 // ValidateNestedPropertyName validates that this string is a valid nested property name 84 func ValidateNestedPropertyName(name, prefix string) error { 85 if !validateNestedPropertyNameRegex.MatchString(name) { 86 return fmt.Errorf("'%s' is not a valid nested property name of '%s'. "+ 87 "NestedProperty names in Weaviate are restricted to valid GraphQL names, "+ 88 "which must be “/%s/”.", name, prefix, NestedPropertyNameRegex) 89 } 90 return nil 91 } 92 93 // ValidateReservedPropertyName validates that a string is not a reserved property name 94 func ValidateReservedPropertyName(name string) error { 95 for i := range reservedPropertyNames { 96 if name == reservedPropertyNames[i] { 97 return fmt.Errorf("'%s' is a reserved property name", name) 98 } 99 } 100 return nil 101 } 102 103 // AssertValidClassName assert that this string is a valid class name or 104 // panics and should therefore most likely not be used 105 func AssertValidClassName(name string) ClassName { 106 n, err := ValidateClassName(name) 107 if err != nil { 108 panic(fmt.Sprintf("Did not expect to be handled '%s', an invalid class name", name)) 109 } 110 return n 111 } 112 113 // AssertValidPropertyName asserts that this string is a valid property name or 114 // panics and should therefore most likely never be used. 115 func AssertValidPropertyName(name string) PropertyName { 116 n, err := ValidatePropertyName(name) 117 if err != nil { 118 panic(fmt.Sprintf("Did not expect to be handled '%s', an invalid property name", name)) 119 } 120 return n 121 }