Spaces:
Sleeping
Sleeping
| // _ _ | |
| // __ _____ __ ___ ___ __ _| |_ ___ | |
| // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
| // \ V V / __/ (_| |\ V /| | (_| | || __/ | |
| // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
| // | |
| // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
| // | |
| // CONTACT: [email protected] | |
| // | |
| package objects | |
| import ( | |
| "context" | |
| "fmt" | |
| "github.com/go-openapi/strfmt" | |
| "github.com/weaviate/weaviate/entities/additional" | |
| "github.com/weaviate/weaviate/entities/models" | |
| ) | |
| // UpdateObject updates object of class. | |
| // If the class contains a network ref, it has a side-effect on the schema: The schema will be updated to | |
| // include this particular network ref class. | |
| func (m *Manager) UpdateObject(ctx context.Context, principal *models.Principal, | |
| class string, id strfmt.UUID, updates *models.Object, | |
| repl *additional.ReplicationProperties, | |
| ) (*models.Object, error) { | |
| path := fmt.Sprintf("objects/%s/%s", class, id) | |
| if class == "" { | |
| path = fmt.Sprintf("objects/%s", id) | |
| } | |
| err := m.authorizer.Authorize(principal, "update", path) | |
| if err != nil { | |
| return nil, err | |
| } | |
| m.metrics.UpdateObjectInc() | |
| defer m.metrics.UpdateObjectDec() | |
| unlock, err := m.locks.LockSchema() | |
| if err != nil { | |
| return nil, NewErrInternal("could not acquire lock: %v", err) | |
| } | |
| defer unlock() | |
| return m.updateObjectToConnectorAndSchema(ctx, principal, class, id, updates, repl) | |
| } | |
| func (m *Manager) updateObjectToConnectorAndSchema(ctx context.Context, | |
| principal *models.Principal, className string, id strfmt.UUID, updates *models.Object, | |
| repl *additional.ReplicationProperties, | |
| ) (*models.Object, error) { | |
| if id != updates.ID { | |
| return nil, NewErrInvalidUserInput("invalid update: field 'id' is immutable") | |
| } | |
| obj, err := m.getObjectFromRepo(ctx, className, id, additional.Properties{}, repl, updates.Tenant) | |
| if err != nil { | |
| return nil, err | |
| } | |
| err = m.autoSchemaManager.autoSchema(ctx, principal, updates, false) | |
| if err != nil { | |
| return nil, NewErrInvalidUserInput("invalid object: %v", err) | |
| } | |
| m.logger. | |
| WithField("object", "kinds_update_requested"). | |
| WithField("original", obj). | |
| WithField("updated", updates). | |
| WithField("id", id). | |
| Debug("received update kind request") | |
| err = m.validateObjectAndNormalizeNames( | |
| ctx, principal, repl, updates, obj.Object()) | |
| if err != nil { | |
| return nil, NewErrInvalidUserInput("invalid object: %v", err) | |
| } | |
| // Set the original creation timestamp before call to put, | |
| // otherwise it is lost. This is because `class` is unmarshalled | |
| // directly from the request body, therefore `CreationTimeUnix` | |
| // inherits the zero value. | |
| updates.CreationTimeUnix = obj.Created | |
| updates.LastUpdateTimeUnix = m.timeSource.Now() | |
| class, err := m.schemaManager.GetClass(ctx, principal, className) | |
| if err != nil { | |
| return nil, err | |
| } | |
| err = m.modulesProvider.UpdateVector(ctx, updates, class, nil, m.findObject, m.logger) | |
| if err != nil { | |
| return nil, NewErrInternal("update object: %v", err) | |
| } | |
| err = m.vectorRepo.PutObject(ctx, updates, updates.Vector, repl) | |
| if err != nil { | |
| return nil, fmt.Errorf("put object: %w", err) | |
| } | |
| return updates, nil | |
| } | |