github.com/weaviate/weaviate@v1.24.6/usecases/objects/update.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 objects
    13  
    14  import (
    15  	"context"
    16  	"fmt"
    17  
    18  	"github.com/go-openapi/strfmt"
    19  	"github.com/weaviate/weaviate/entities/additional"
    20  	"github.com/weaviate/weaviate/entities/models"
    21  	"github.com/weaviate/weaviate/entities/moduletools"
    22  )
    23  
    24  // UpdateObject updates object of class.
    25  // If the class contains a network ref, it has a side-effect on the schema: The schema will be updated to
    26  // include this particular network ref class.
    27  func (m *Manager) UpdateObject(ctx context.Context, principal *models.Principal,
    28  	class string, id strfmt.UUID, updates *models.Object,
    29  	repl *additional.ReplicationProperties,
    30  ) (*models.Object, error) {
    31  	path := fmt.Sprintf("objects/%s/%s", class, id)
    32  	if class == "" {
    33  		path = fmt.Sprintf("objects/%s", id)
    34  	}
    35  	err := m.authorizer.Authorize(principal, "update", path)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	m.metrics.UpdateObjectInc()
    41  	defer m.metrics.UpdateObjectDec()
    42  
    43  	unlock, err := m.locks.LockSchema()
    44  	if err != nil {
    45  		return nil, NewErrInternal("could not acquire lock: %v", err)
    46  	}
    47  	defer unlock()
    48  
    49  	return m.updateObjectToConnectorAndSchema(ctx, principal, class, id, updates, repl)
    50  }
    51  
    52  func (m *Manager) updateObjectToConnectorAndSchema(ctx context.Context,
    53  	principal *models.Principal, className string, id strfmt.UUID, updates *models.Object,
    54  	repl *additional.ReplicationProperties,
    55  ) (*models.Object, error) {
    56  	if id != updates.ID {
    57  		return nil, NewErrInvalidUserInput("invalid update: field 'id' is immutable")
    58  	}
    59  
    60  	obj, err := m.getObjectFromRepo(ctx, className, id, additional.Properties{}, repl, updates.Tenant)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	err = m.autoSchemaManager.autoSchema(ctx, principal, updates, false)
    66  	if err != nil {
    67  		return nil, NewErrInvalidUserInput("invalid object: %v", err)
    68  	}
    69  
    70  	m.logger.
    71  		WithField("object", "kinds_update_requested").
    72  		WithField("original", obj).
    73  		WithField("updated", updates).
    74  		WithField("id", id).
    75  		Debug("received update kind request")
    76  
    77  	prevObj := obj.Object()
    78  	err = m.validateObjectAndNormalizeNames(
    79  		ctx, principal, repl, updates, prevObj)
    80  	if err != nil {
    81  		return nil, NewErrInvalidUserInput("invalid object: %v", err)
    82  	}
    83  
    84  	// Set the original creation timestamp before call to put,
    85  	// otherwise it is lost. This is because `class` is unmarshalled
    86  	// directly from the request body, therefore `CreationTimeUnix`
    87  	// inherits the zero value.
    88  	updates.CreationTimeUnix = obj.Created
    89  	updates.LastUpdateTimeUnix = m.timeSource.Now()
    90  
    91  	class, err := m.schemaManager.GetClass(ctx, principal, className)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	compFactory := func() (moduletools.VectorizablePropsComparator, error) {
    96  		return moduletools.NewVectorizablePropsComparator(class.Properties, updates.Properties,
    97  			prevObj.Properties, prevObj.Vector, prevObj.Vectors), nil
    98  	}
    99  	err = m.modulesProvider.UpdateVector(ctx, updates, class, compFactory, m.findObject, m.logger)
   100  	if err != nil {
   101  		return nil, NewErrInternal("update object: %v", err)
   102  	}
   103  
   104  	err = m.vectorRepo.PutObject(ctx, updates, updates.Vector, updates.Vectors, repl)
   105  	if err != nil {
   106  		return nil, fmt.Errorf("put object: %w", err)
   107  	}
   108  
   109  	return updates, nil
   110  }