-
Notifications
You must be signed in to change notification settings - Fork 81
added len method #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
added len method #708
Changes from all commits
c5f671c
78505d2
2add54e
45ab135
4d4dc5e
d40feb9
f5c2f6d
a9953cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,6 +24,8 @@ import ( | |||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||
| "io" | ||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||
| "reflect" | ||||||||||||||||||||||||||||
| "sync" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| "github.com/pkg/errors" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -49,6 +51,13 @@ func (c collectionDocumentCreate) CreateDocumentsWithOptions(ctx context.Context | |||||||||||||||||||||||||||
| return nil, errors.Errorf("Input documents should be list") | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Get document count from input (same as v1 approach) | ||||||||||||||||||||||||||||
| documentsVal := reflect.ValueOf(documents) | ||||||||||||||||||||||||||||
| if documentsVal.Kind() == reflect.Ptr { | ||||||||||||||||||||||||||||
| documentsVal = documentsVal.Elem() | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| documentCount := documentsVal.Len() | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| url := c.collection.url("document") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| req, err := c.collection.connection().NewRequest(http.MethodPost, url) | ||||||||||||||||||||||||||||
|
|
@@ -73,7 +82,7 @@ func (c collectionDocumentCreate) CreateDocumentsWithOptions(ctx context.Context | |||||||||||||||||||||||||||
| case http.StatusCreated: | ||||||||||||||||||||||||||||
| fallthrough | ||||||||||||||||||||||||||||
| case http.StatusAccepted: | ||||||||||||||||||||||||||||
| return newCollectionDocumentCreateResponseReader(&arr, opts), nil | ||||||||||||||||||||||||||||
| return newCollectionDocumentCreateResponseReader(&arr, opts, documentCount), nil | ||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||
| return nil, shared.NewResponseStruct().AsArangoErrorWithCode(code) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
@@ -125,44 +134,64 @@ func (c collectionDocumentCreate) CreateDocument(ctx context.Context, document i | |||||||||||||||||||||||||||
| return c.CreateDocumentWithOptions(ctx, document, nil) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| func newCollectionDocumentCreateResponseReader(array *connection.Array, options *CollectionDocumentCreateOptions) *collectionDocumentCreateResponseReader { | ||||||||||||||||||||||||||||
| c := &collectionDocumentCreateResponseReader{array: array, options: options} | ||||||||||||||||||||||||||||
| func newCollectionDocumentCreateResponseReader(array *connection.Array, options *CollectionDocumentCreateOptions, documentCount int) *collectionDocumentCreateResponseReader { | ||||||||||||||||||||||||||||
| c := &collectionDocumentCreateResponseReader{ | ||||||||||||||||||||||||||||
| array: array, | ||||||||||||||||||||||||||||
| options: options, | ||||||||||||||||||||||||||||
| documentCount: documentCount, | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if c.options != nil { | ||||||||||||||||||||||||||||
| c.response.Old = newUnmarshalInto(c.options.OldObject) | ||||||||||||||||||||||||||||
| c.response.New = newUnmarshalInto(c.options.NewObject) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| c.ReadAllReader = shared.ReadAllReader[CollectionDocumentCreateResponse, *collectionDocumentCreateResponseReader]{Reader: c} | ||||||||||||||||||||||||||||
| return c | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| var _ CollectionDocumentCreateResponseReader = &collectionDocumentCreateResponseReader{} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| type collectionDocumentCreateResponseReader struct { | ||||||||||||||||||||||||||||
| array *connection.Array | ||||||||||||||||||||||||||||
| options *CollectionDocumentCreateOptions | ||||||||||||||||||||||||||||
| response struct { | ||||||||||||||||||||||||||||
| array *connection.Array | ||||||||||||||||||||||||||||
| options *CollectionDocumentCreateOptions | ||||||||||||||||||||||||||||
| documentCount int // Store input document count for Len() without caching | ||||||||||||||||||||||||||||
| response struct { | ||||||||||||||||||||||||||||
| *DocumentMeta | ||||||||||||||||||||||||||||
| *shared.ResponseStruct `json:",inline"` | ||||||||||||||||||||||||||||
| Old *UnmarshalInto `json:"old,omitempty"` | ||||||||||||||||||||||||||||
| New *UnmarshalInto `json:"new,omitempty"` | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| shared.ReadAllReader[CollectionDocumentCreateResponse, *collectionDocumentCreateResponseReader] | ||||||||||||||||||||||||||||
| mu sync.Mutex | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| func (c *collectionDocumentCreateResponseReader) Read() (CollectionDocumentCreateResponse, error) { | ||||||||||||||||||||||||||||
| c.mu.Lock() | ||||||||||||||||||||||||||||
| defer c.mu.Unlock() | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if !c.array.More() { | ||||||||||||||||||||||||||||
| return CollectionDocumentCreateResponse{}, shared.NoMoreDocumentsError{} | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| var meta CollectionDocumentCreateResponse | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Create new instances for each document to avoid pointer reuse | ||||||||||||||||||||||||||||
| if c.options != nil { | ||||||||||||||||||||||||||||
| meta.Old = c.options.OldObject | ||||||||||||||||||||||||||||
| meta.New = c.options.NewObject | ||||||||||||||||||||||||||||
| if c.options.OldObject != nil { | ||||||||||||||||||||||||||||
| oldObjectType := reflect.TypeOf(c.options.OldObject).Elem() | ||||||||||||||||||||||||||||
| meta.Old = reflect.New(oldObjectType).Interface() | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| if c.options.NewObject != nil { | ||||||||||||||||||||||||||||
| newObjectType := reflect.TypeOf(c.options.NewObject).Elem() | ||||||||||||||||||||||||||||
| meta.New = reflect.New(newObjectType).Interface() | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| c.response.DocumentMeta = &meta.DocumentMeta | ||||||||||||||||||||||||||||
| c.response.ResponseStruct = &meta.ResponseStruct | ||||||||||||||||||||||||||||
| c.response.Old = newUnmarshalInto(meta.Old) | ||||||||||||||||||||||||||||
| c.response.New = newUnmarshalInto(meta.New) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if err := c.array.Unmarshal(&c.response); err != nil { | ||||||||||||||||||||||||||||
| if err == io.EOF { | ||||||||||||||||||||||||||||
|
|
@@ -175,5 +204,26 @@ func (c *collectionDocumentCreateResponseReader) Read() (CollectionDocumentCreat | |||||||||||||||||||||||||||
| return meta, meta.AsArangoError() | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Copy data from the new instances back to the original option objects for backward compatibility | ||||||||||||||||||||||||||||
| if c.options != nil { | ||||||||||||||||||||||||||||
| if c.options.OldObject != nil && meta.Old != nil { | ||||||||||||||||||||||||||||
| oldValue := reflect.ValueOf(meta.Old).Elem() | ||||||||||||||||||||||||||||
| originalValue := reflect.ValueOf(c.options.OldObject).Elem() | ||||||||||||||||||||||||||||
| originalValue.Set(oldValue) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| if c.options.NewObject != nil && meta.New != nil { | ||||||||||||||||||||||||||||
| newValue := reflect.ValueOf(meta.New).Elem() | ||||||||||||||||||||||||||||
| originalValue := reflect.ValueOf(c.options.NewObject).Elem() | ||||||||||||||||||||||||||||
| originalValue.Set(newValue) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
Comment on lines
+207
to
+220
|
||||||||||||||||||||||||||||
| // Copy data from the new instances back to the original option objects for backward compatibility | |
| if c.options != nil { | |
| if c.options.OldObject != nil && meta.Old != nil { | |
| oldValue := reflect.ValueOf(meta.Old).Elem() | |
| originalValue := reflect.ValueOf(c.options.OldObject).Elem() | |
| originalValue.Set(oldValue) | |
| } | |
| if c.options.NewObject != nil && meta.New != nil { | |
| newValue := reflect.ValueOf(meta.New).Elem() | |
| originalValue := reflect.ValueOf(c.options.NewObject).Elem() | |
| originalValue.Set(newValue) | |
| } | |
| } |
bluepal-prasanthi-moparthi marked this conversation as resolved.
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,6 +24,8 @@ import ( | |||||||||||
| "context" | ||||||||||||
| "io" | ||||||||||||
| "net/http" | ||||||||||||
| "reflect" | ||||||||||||
| "sync" | ||||||||||||
|
|
||||||||||||
| "github.com/pkg/errors" | ||||||||||||
|
|
||||||||||||
|
|
@@ -42,6 +44,7 @@ var _ CollectionDocumentDelete = &collectionDocumentDelete{} | |||||||||||
|
|
||||||||||||
| type collectionDocumentDelete struct { | ||||||||||||
| collection *collection | ||||||||||||
| shared.ReadAllIntoReader[CollectionDocumentDeleteResponse, *collectionDocumentDeleteResponseReader] | ||||||||||||
|
||||||||||||
| shared.ReadAllIntoReader[CollectionDocumentDeleteResponse, *collectionDocumentDeleteResponseReader] |
Copilot
AI
Dec 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reflection code assumes that OldObject is a non-nil pointer, but doesn't validate this before calling Elem(). If OldObject is nil (despite the nil check on line 169), reflect.TypeOf(c.options.OldObject) will return nil, and calling .Elem() on it will panic. Consider adding validation that the pointer is not nil after the options check.
Copilot
AI
Dec 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The back-propagation to c.options.OldObject via reflection (lines 179-182) creates a potential data race if the same options object is shared across multiple concurrent Read() calls or readers. While the mutex protects the Read() method itself, if the same options object is passed to multiple readers, concurrent writes to the same options object could race. Consider documenting that options objects should not be shared across concurrent operations, or design this differently to avoid the race.
| // Copy data from the new instance to the original OldObject for backward compatibility | |
| oldValue := reflect.ValueOf(meta.Old).Elem() | |
| originalValue := reflect.ValueOf(c.options.OldObject).Elem() | |
| originalValue.Set(oldValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reflection code assumes that
OldObjectandNewObjectare non-nil pointers, but doesn't validate this before callingElem(). IfOldObjectis nil,reflect.TypeOf(c.options.OldObject)will return nil, and calling.Elem()on it will panic. This same issue exists in lines 181-188 and 209-218. Consider adding nil checks or handling the nil case gracefully.