Skip to content

Commit d185cdb

Browse files
authored
[Feature] [V2] Code fields collision (#656)
1 parent b9d11b8 commit d185cdb

9 files changed

+293
-95
lines changed

v2/arangodb/collection_documents_delete_impl.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,37 @@ func (c *collectionDocumentDeleteResponseReader) Read(i interface{}) (Collection
120120

121121
var meta CollectionDocumentDeleteResponse
122122

123-
if c.options != nil {
124-
meta.Old = c.options.OldObject
125-
}
123+
var response Unmarshal[shared.ResponseStruct, Unmarshal[DocumentMeta, UnmarshalData]]
126124

127-
if err := c.array.Unmarshal(newMultiUnmarshaller(&meta, newUnmarshalInto(i))); err != nil {
125+
if err := c.array.Unmarshal(&response); err != nil {
128126
if err == io.EOF {
129127
return CollectionDocumentDeleteResponse{}, shared.NoMoreDocumentsError{}
130128
}
131129
return CollectionDocumentDeleteResponse{}, err
132130
}
133131

132+
if q := response.Current; q != nil {
133+
meta.ResponseStruct = *q
134+
}
135+
136+
if q := response.Object.Current; q != nil {
137+
meta.DocumentMeta = *q
138+
}
139+
134140
if meta.Error != nil && *meta.Error {
135141
return meta, meta.AsArangoError()
136142
}
137143

144+
if err := response.Object.Object.Inject(i); err != nil {
145+
return CollectionDocumentDeleteResponse{}, err
146+
}
147+
148+
if c.options != nil && c.options.OldObject != nil {
149+
meta.Old = c.options.OldObject
150+
if err := response.Object.Object.Extract("old").Inject(meta.Old); err != nil {
151+
return CollectionDocumentDeleteResponse{}, err
152+
}
153+
}
154+
138155
return meta, nil
139156
}

v2/arangodb/collection_documents_read_impl.go

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020-2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -74,23 +74,24 @@ func (c collectionDocumentRead) ReadDocument(ctx context.Context, key string, re
7474
func (c collectionDocumentRead) ReadDocumentWithOptions(ctx context.Context, key string, result interface{}, opts *CollectionDocumentReadOptions) (DocumentMeta, error) {
7575
url := c.collection.url("document", key)
7676

77-
var response struct {
78-
shared.ResponseStruct `json:",inline"`
79-
DocumentMeta `json:",inline"`
80-
}
81-
82-
data := newUnmarshalInto(result)
77+
var response Unmarshal[shared.ResponseStruct, Unmarshal[DocumentMeta, UnmarshalData]]
8378

84-
resp, err := connection.CallGet(ctx, c.collection.connection(), url, newMultiUnmarshaller(&response, data), c.collection.withModifiers(opts.modifyRequest)...)
79+
resp, err := connection.CallGet(ctx, c.collection.connection(), url, &response, c.collection.withModifiers(opts.modifyRequest)...)
8580
if err != nil {
8681
return DocumentMeta{}, err
8782
}
8883

8984
switch code := resp.Code(); code {
9085
case http.StatusOK:
91-
return response.DocumentMeta, nil
86+
if err := response.Object.Object.Inject(result); err != nil {
87+
return DocumentMeta{}, err
88+
}
89+
if z := response.Object.Current; z != nil {
90+
return *z, nil
91+
}
92+
return DocumentMeta{}, nil
9293
default:
93-
return DocumentMeta{}, response.AsArangoErrorWithCode(code)
94+
return DocumentMeta{}, response.Current.AsArangoErrorWithCode(code)
9495
}
9596
}
9697

@@ -112,18 +113,32 @@ func (c *collectionDocumentReadResponseReader) Read(i interface{}) (CollectionDo
112113
return CollectionDocumentReadResponse{}, shared.NoMoreDocumentsError{}
113114
}
114115

115-
var meta CollectionDocumentReadResponse
116+
var response Unmarshal[shared.ResponseStruct, Unmarshal[DocumentMeta, UnmarshalData]]
116117

117-
if err := c.array.Unmarshal(newMultiUnmarshaller(&meta, newUnmarshalInto(i))); err != nil {
118+
if err := c.array.Unmarshal(&response); err != nil {
118119
if err == io.EOF {
119120
return CollectionDocumentReadResponse{}, shared.NoMoreDocumentsError{}
120121
}
121122
return CollectionDocumentReadResponse{}, err
122123
}
123124

125+
var meta CollectionDocumentReadResponse
126+
127+
if q := response.Current; q != nil {
128+
meta.ResponseStruct = *q
129+
}
130+
131+
if q := response.Object.Current; q != nil {
132+
meta.DocumentMeta = *q
133+
}
134+
124135
if meta.Error != nil && *meta.Error {
125136
return meta, meta.AsArangoError()
126137
}
127138

139+
if err := response.Object.Object.Inject(i); err != nil {
140+
return CollectionDocumentReadResponse{}, err
141+
}
142+
128143
return meta, nil
129144
}

v2/arangodb/collection_indexes_impl.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,24 +228,27 @@ func (c *collectionIndexes) EnsureInvertedIndex(ctx context.Context, options *In
228228
func (c *collectionIndexes) ensureIndex(ctx context.Context, reqData interface{}, result interface{}) (bool, error) {
229229
urlEndpoint := c.collection.db.url("_api", "index")
230230

231-
var response struct {
232-
shared.ResponseStruct `json:",inline"`
233-
}
234-
data := newUnmarshalInto(&result)
231+
var response Unmarshal[shared.ResponseStruct, UnmarshalData]
235232

236-
resp, err := connection.CallPost(ctx, c.collection.connection(), urlEndpoint, newMultiUnmarshaller(&response, data), &reqData,
233+
resp, err := connection.CallPost(ctx, c.collection.connection(), urlEndpoint, &response, &reqData,
237234
c.collection.withModifiers(connection.WithQuery("collection", c.collection.name))...)
238235
if err != nil {
239236
return false, errors.WithStack(err)
240237
}
241238

242239
switch code := resp.Code(); code {
243240
case http.StatusOK:
241+
if err := response.Object.Inject(result); err != nil {
242+
return false, err
243+
}
244244
return false, nil
245245
case http.StatusCreated:
246+
if err := response.Object.Inject(result); err != nil {
247+
return false, err
248+
}
246249
return true, nil
247250
default:
248-
return false, response.AsArangoErrorWithCode(code)
251+
return false, response.Current.AsArangoErrorWithCode(code)
249252
}
250253
}
251254

v2/arangodb/cursor_impl.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020-2023 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -144,22 +144,21 @@ func (c *cursor) readDocument(ctx context.Context, result interface{}) (Document
144144
}
145145
}
146146

147-
var data byteDecoder
148-
if err := c.data.Result.Read(&data); err != nil {
147+
var res Unmarshal[DocumentMeta, UnmarshalData]
148+
149+
if err := c.data.Result.Read(&res); err != nil {
149150
return DocumentMeta{}, err
150151
}
151152

152-
var meta DocumentMeta
153-
154-
if err := data.Unmarshal(&meta); err != nil {
155-
// Ignore error
153+
if err := res.Object.Inject(result); err != nil {
154+
return DocumentMeta{}, err
156155
}
157156

158-
if err := data.Unmarshal(result); err != nil {
159-
return DocumentMeta{}, err
157+
if m := res.Current; m != nil {
158+
return *m, nil
160159
}
161160

162-
return meta, nil
161+
return DocumentMeta{}, nil
163162
}
164163

165164
func (c *cursor) getNextBatch(ctx context.Context, retryBatchID string) error {

v2/arangodb/database_transaction_impl.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,17 @@ func (d databaseTransaction) listTransactionsWithStatuses(ctx context.Context, s
6060
} `json:"transactions,omitempty"`
6161
}
6262

63-
var response shared.ResponseStruct
63+
var response Unmarshal[shared.ResponseStruct, UnmarshalData]
6464

65-
resp, err := connection.CallGet(ctx, d.db.connection(), url, newMultiUnmarshaller(&result, &response), d.db.modifiers...)
65+
resp, err := connection.CallGet(ctx, d.db.connection(), url, &response, d.db.modifiers...)
6666
if err != nil {
6767
return nil, errors.WithStack(err)
6868
}
6969

70+
if err := response.Object.Inject(&result); err != nil {
71+
return nil, err
72+
}
73+
7074
switch code := resp.Code(); code {
7175
case http.StatusOK:
7276
var t []Transaction
@@ -80,7 +84,7 @@ func (d databaseTransaction) listTransactionsWithStatuses(ctx context.Context, s
8084

8185
return t, nil
8286
default:
83-
return nil, response.AsArangoErrorWithCode(code)
87+
return nil, response.Current.AsArangoErrorWithCode(code)
8488
}
8589
}
8690

v2/arangodb/unmarshaller.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package arangodb
22+
23+
import (
24+
"encoding/json"
25+
26+
"github.com/pkg/errors"
27+
)
28+
29+
type Unmarshaler interface {
30+
json.Unmarshaler
31+
32+
Inject(object any) error
33+
Extract(key string) Unmarshaler
34+
}
35+
36+
type Unmarshal[C, T any] struct {
37+
Current *C
38+
39+
Object T
40+
}
41+
42+
func (u *Unmarshal[C, T]) UnmarshalJSON(bytes []byte) error {
43+
u.Current = nil
44+
45+
var q C
46+
47+
if err := json.Unmarshal(bytes, &q); err == nil {
48+
u.Current = &q
49+
}
50+
51+
return json.Unmarshal(bytes, &u.Object)
52+
}
53+
54+
type UnmarshalData []byte
55+
56+
func (u *UnmarshalData) Inject(object any) error {
57+
if u == nil {
58+
return errors.Errorf("Data provided is nil")
59+
}
60+
61+
return json.Unmarshal(*u, object)
62+
}
63+
64+
func (u *UnmarshalData) Extract(key string) Unmarshaler {
65+
if u == nil {
66+
return errorUnmarshalData{err: errors.Errorf("Data provided is nil")}
67+
}
68+
69+
var z map[string]UnmarshalData
70+
71+
if err := json.Unmarshal(*u, &z); err != nil {
72+
return errorUnmarshalData{err: err}
73+
}
74+
75+
if v, ok := z[key]; ok {
76+
return &v
77+
}
78+
79+
return errorUnmarshalData{err: errors.Errorf("Key %s not found", key)}
80+
}
81+
82+
func (u *UnmarshalData) UnmarshalJSON(bytes []byte) error {
83+
if u == nil {
84+
return errors.Errorf("Data provided is nil")
85+
}
86+
87+
z := make([]byte, len(bytes))
88+
89+
copy(z, bytes)
90+
91+
*u = z
92+
return nil
93+
}
94+
95+
type errorUnmarshalData struct {
96+
err error
97+
}
98+
99+
func (e errorUnmarshalData) UnmarshalJSON(bytes []byte) error {
100+
return e.err
101+
}
102+
103+
func (e errorUnmarshalData) Inject(object any) error {
104+
return e.err
105+
}
106+
107+
func (e errorUnmarshalData) Extract(key string) Unmarshaler {
108+
return e
109+
}

v2/arangodb/utils.go

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -30,65 +30,6 @@ import (
3030
"github.com/pkg/errors"
3131
)
3232

33-
var _ json.Unmarshaler = &multiUnmarshaller{}
34-
var _ json.Marshaler = &multiUnmarshaller{}
35-
36-
func newMultiUnmarshaller(obj ...interface{}) json.Unmarshaler {
37-
return &multiUnmarshaller{
38-
obj: obj,
39-
}
40-
}
41-
42-
type multiUnmarshaller struct {
43-
obj []interface{}
44-
}
45-
46-
func (m multiUnmarshaller) MarshalJSON() ([]byte, error) {
47-
r := map[string]interface{}{}
48-
for _, o := range m.obj {
49-
z := map[string]interface{}{}
50-
if d, err := json.Marshal(o); err != nil {
51-
return nil, err
52-
} else {
53-
if err := json.Unmarshal(d, &z); err != nil {
54-
return nil, err
55-
}
56-
}
57-
58-
for k, v := range z {
59-
r[k] = v
60-
}
61-
}
62-
63-
return json.Marshal(r)
64-
}
65-
66-
func (m multiUnmarshaller) UnmarshalJSON(d []byte) error {
67-
for _, o := range m.obj {
68-
if err := json.Unmarshal(d, o); err != nil {
69-
return err
70-
}
71-
}
72-
73-
return nil
74-
}
75-
76-
type byteDecoder struct {
77-
data []byte
78-
}
79-
80-
func (b *byteDecoder) UnmarshalJSON(d []byte) error {
81-
b.data = make([]byte, len(d))
82-
83-
copy(b.data, d)
84-
85-
return nil
86-
}
87-
88-
func (b *byteDecoder) Unmarshal(i interface{}) error {
89-
return json.Unmarshal(b.data, i)
90-
}
91-
9233
func newUnmarshalInto(obj interface{}) *UnmarshalInto {
9334
return &UnmarshalInto{obj}
9435
}

0 commit comments

Comments
 (0)