arangodb / go-driver

The official ArangoDB go driver.
Apache License 2.0
341 stars 79 forks source link

Return new documents from UpdateDocumentsWithOptions #633

Open thomaskrut opened 2 weeks ago

thomaskrut commented 2 weeks ago

I'm having trouble returning the created documents from UpdateDocumentsWithOptions(). I also noticed there are no tests for this method, only for the single document update.

This works fine (updating a single document), the updated document is returned from the function:

func (c *Client[T]) Update(ctx context.Context, item T, key string) (T, error) {
    var updated T
    opts := &arangodb.CollectionDocumentUpdateOptions{
        NewObject: &updated,
    }

    if _, err := dbc.collection.UpdateDocumentWithOptions(ctx, key, item, opts); err != nil {
        return nil, err
    }
    return updated, nil
}

This however returns an empty slice:

func (dbc *Client[T]) UpdateMany(ctx context.Context, items []T) ([]T, error) {
    var updated []T

    opts := &arangodb.CollectionDocumentUpdateOptions{
        NewObject: &updated,
    }

    if _, err := dbc.collection.UpdateDocumentsWithOptions(ctx, items, opts); err != nil {
        return updated, dbc.handleError(ctx, "update document", err)
    }

    return updated, nil
}

Manual checks confirm that the documents are properly updated in the database. I tried calling Read()on the response object but got an error message: json: cannot unmarshal object into Go struct field .new of type []*<myType>

jwierzbo commented 1 week ago

@thomaskrut This method is tested here with 512 docs (Read method is verified as well): https://github.com/arangodb/go-driver/blob/baee6a4c8e85c471076778521a60cc23ade36f74/v2/tests/database_collection_operations_test.go#L445-L453

The problem is probably with the generics and your Client structure config. Could you share more code?

thomaskrut commented 1 week ago

Thanks for pointing out the test for me. I realized that I should not be passing a slice as NewObject on the options struct. If I instead pass an instance of T, I do get the updated document by reading that variable for each iteration on meta.Read().

However this approach does not easily let me append these documents to a slice and return them from the function, as the slice will end up with pointers to the last document read. Also, doing type assertion on meta.New and appending those objects yields the same result.