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  }