SemanticSearchPOC / usecases /modules /module_config_init_and_validate.go
KevinStephenson
Adding in weaviate code
b110593
raw
history blame
4.2 kB
// _ _
// __ _____ __ ___ ___ __ _| |_ ___
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
// \ V V / __/ (_| |\ V /| | (_| | || __/
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
//
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
//
// CONTACT: [email protected]
//
package modules
import (
"context"
"github.com/pkg/errors"
"github.com/weaviate/weaviate/entities/models"
"github.com/weaviate/weaviate/entities/modulecapabilities"
"github.com/weaviate/weaviate/entities/schema"
)
// SetClassDefaults sets the module-specific defaults for the class itself, but
// also for each prop
func (p *Provider) SetClassDefaults(class *models.Class) {
if class.Vectorizer == "none" {
// the class does not use a vectorizer, nothing to do for us
return
}
mod := p.GetByName(class.Vectorizer)
cc, ok := mod.(modulecapabilities.ClassConfigurator)
if !ok {
// the module exists, but is not a class configurator, nothing to do for us
return
}
cfg := NewClassBasedModuleConfig(class, class.Vectorizer, "")
p.setPerClassConfigDefaults(class, cfg, cc)
p.setPerPropertyConfigDefaults(class, cfg, cc)
}
// SetSinglePropertyDefaults can be used when a property is added later, e.g.
// as part of merging in a ref prop after a class has already been created
func (p *Provider) SetSinglePropertyDefaults(class *models.Class,
prop *models.Property,
) {
if class.Vectorizer == "none" {
// the class does not use a vectorizer, nothing to do for us
return
}
mod := p.GetByName(class.Vectorizer)
cc, ok := mod.(modulecapabilities.ClassConfigurator)
if !ok {
// the module exists, but is not a class configurator, nothing to do for us
return
}
p.setSinglePropertyConfigDefaults(class, prop, cc)
}
func (p *Provider) setPerClassConfigDefaults(class *models.Class,
cfg *ClassBasedModuleConfig, cc modulecapabilities.ClassConfigurator,
) {
modDefaults := cc.ClassConfigDefaults()
userSpecified := cfg.Class()
mergedConfig := map[string]interface{}{}
for key, value := range modDefaults {
mergedConfig[key] = value
}
for key, value := range userSpecified {
mergedConfig[key] = value
}
if class.ModuleConfig == nil {
class.ModuleConfig = map[string]interface{}{}
}
class.ModuleConfig.(map[string]interface{})[class.Vectorizer] = mergedConfig
}
func (p *Provider) setPerPropertyConfigDefaults(class *models.Class,
cfg *ClassBasedModuleConfig, cc modulecapabilities.ClassConfigurator,
) {
for _, prop := range class.Properties {
p.setSinglePropertyConfigDefaults(class, prop, cc)
}
}
func (p *Provider) setSinglePropertyConfigDefaults(class *models.Class,
prop *models.Property, cc modulecapabilities.ClassConfigurator,
) {
dt, _ := schema.GetValueDataTypeFromString(prop.DataType[0])
modDefaults := cc.PropertyConfigDefaults(dt)
mergedConfig := map[string]interface{}{}
userSpecified := make(map[string]interface{})
if prop.ModuleConfig != nil {
userSpecified = prop.ModuleConfig.(map[string]interface{})[class.Vectorizer].(map[string]interface{})
}
for key, value := range modDefaults {
mergedConfig[key] = value
}
for key, value := range userSpecified {
mergedConfig[key] = value
}
if prop.ModuleConfig == nil {
prop.ModuleConfig = map[string]interface{}{}
}
prop.ModuleConfig.(map[string]interface{})[class.Vectorizer] = mergedConfig
}
func (p *Provider) ValidateClass(ctx context.Context, class *models.Class) error {
if class.Vectorizer == "none" {
// the class does not use a vectorizer, nothing to do for us
return nil
}
moduleConfig, ok := class.ModuleConfig.(map[string]interface{})
if !ok {
return nil
}
for key := range moduleConfig {
mod := p.GetByName(key)
cc, ok := mod.(modulecapabilities.ClassConfigurator)
if !ok {
// the module exists, but is not a class configurator, nothing to do for us
return nil
}
cfg := NewClassBasedModuleConfig(class, key, "")
err := cc.ValidateClass(ctx, class, cfg)
if err != nil {
return errors.Wrapf(err, "module '%s'", key)
}
}
return nil
}