Skip to content

Commit f573d58

Browse files
authored
Merge pull request #471 from aerospike/v7_stage
Go Client v7.9.0
2 parents aa8b342 + 5327cca commit f573d58

File tree

6 files changed

+83
-60
lines changed

6 files changed

+83
-60
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Change History
22

3+
4+
## February 26 2025: v7.9.0
5+
6+
- **New Features**
7+
- [CLIENT-3334] Support old PHP7 client encoded boolean and null values.
8+
9+
- **Fixes**
10+
- [CLIENT-3348] Parsing error during node rack update.
11+
312
## December 19 2024: v7.8.0
413

514
Minor fix release.

client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ var _ = gg.Describe("Aerospike", func() {
203203
c, err := as.NewClientWithPolicyAndHost(&cpolicy, dbHost)
204204
gm.Expect(err).NotTo(gm.HaveOccurred())
205205

206-
info := info(c, "racks:")
206+
info := info(c, "rack-ids")
207207
if strings.HasPrefix(strings.ToUpper(info), "ERROR") {
208208
gg.Skip("Skipping RackAware test since it is not supported on this cluster...")
209209
}

node.go

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
package aerospike
1616

1717
import (
18-
"bufio"
1918
"errors"
20-
"io"
2119
"strconv"
2220
"strings"
2321
"time"
@@ -143,7 +141,7 @@ func (nd *Node) Refresh(peers *peers) Error {
143141
var infoMap map[string]string
144142
commands := []string{"node", "peers-generation", "partition-generation"}
145143
if nd.cluster.clientPolicy.RackAware {
146-
commands = append(commands, "racks:")
144+
commands = append(commands, "rack-ids")
147145
}
148146

149147
infoMap, err := nd.RequestInfo(&nd.cluster.infoPolicy, commands...)
@@ -174,7 +172,7 @@ func (nd *Node) Refresh(peers *peers) Error {
174172
return err
175173
}
176174
// Should not fail in other cases
177-
logger.Logger.Warn("Updating node rack info failed with error: %s (racks: `%s`)", err, infoMap["racks:"])
175+
logger.Logger.Warn("Updating node rack info failed with error: %s (rack-ids: `%s`)", err, infoMap["rack-ids"])
178176
}
179177

180178
nd.failures.Set(0)
@@ -228,57 +226,31 @@ func (nd *Node) updateRackInfo(infoMap map[string]string) Error {
228226
return nil
229227
}
230228

231-
// Do not raise an error if the server does not support rackaware
232-
if strings.HasPrefix(strings.ToUpper(infoMap["racks:"]), "ERROR") {
229+
// Receive format: <ns1>:<rack1>;<ns2>:<rack2>...
230+
rackIds := infoMap["rack-ids"]
231+
232+
// Do not panic if the server does not support rackaware
233+
if len(rackIds) == 0 || strings.HasPrefix(strings.ToUpper(rackIds), "ERROR") {
233234
return newError(types.UNSUPPORTED_FEATURE, "You have set the ClientPolicy.RackAware = true, but the server does not support this feature.")
234235
}
235236

236-
ss := strings.Split(infoMap["racks:"], ";")
237-
racks := map[string]int{}
238-
for _, s := range ss {
239-
in := bufio.NewReader(strings.NewReader(s))
240-
_, err := in.ReadString('=')
241-
if err != nil {
242-
return newErrorAndWrap(err, types.PARSE_ERROR)
237+
rackPairs := strings.Split(rackIds, ";")
238+
racks := make(map[string]int)
239+
for i := range rackPairs {
240+
// split at the last occurrence of `:` to ensure rack will be an integer
241+
lastIdx := strings.LastIndex(rackPairs[i], ":")
242+
if lastIdx < 0 {
243+
return newError(types.PARSE_ERROR, "invalid rack value `%s`", rackPairs[i])
243244
}
244245

245-
ns, err := in.ReadString(':')
246+
ns := rackPairs[i][:lastIdx]
247+
rack := rackPairs[i][lastIdx+1:]
248+
249+
rackNo, err := strconv.Atoi(rack)
246250
if err != nil {
247251
return newErrorAndWrap(err, types.PARSE_ERROR)
248252
}
249-
250-
for {
251-
_, err = in.ReadString('_')
252-
if err != nil {
253-
return newErrorAndWrap(err, types.PARSE_ERROR)
254-
}
255-
256-
rackStr, err := in.ReadString('=')
257-
if err != nil {
258-
return newErrorAndWrap(err, types.PARSE_ERROR)
259-
}
260-
261-
rack, err := strconv.Atoi(rackStr[:len(rackStr)-1])
262-
if err != nil {
263-
return newErrorAndWrap(err, types.PARSE_ERROR)
264-
}
265-
266-
nodesList, err := in.ReadString(':')
267-
if err != nil && err != io.EOF {
268-
return newErrorAndWrap(err, types.PARSE_ERROR)
269-
}
270-
271-
nodes := strings.Split(strings.Trim(nodesList, ":"), ",")
272-
for i := range nodes {
273-
if nodes[i] == nd.name {
274-
racks[ns[:len(ns)-1]] = rack
275-
}
276-
}
277-
278-
if err == io.EOF {
279-
break
280-
}
281-
}
253+
racks[ns] = rackNo
282254
}
283255

284256
nd.racks.Set(racks)

types/particle_type/particle_type.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@ package particleType
1717
// Server particle types. Unsupported types are commented out.
1818
const (
1919
//revive:disable
20-
NULL = 0
21-
INTEGER = 1
22-
FLOAT = 2
23-
STRING = 3
24-
BLOB = 4
25-
DIGEST = 6
26-
BOOL = 17
27-
HLL = 18
28-
MAP = 19
29-
LIST = 20
30-
LDT = 21
31-
GEOJSON = 23
20+
NULL = 0
21+
INTEGER = 1
22+
FLOAT = 2
23+
STRING = 3
24+
BLOB = 4
25+
DIGEST = 6
26+
PHP_BLOB = 11 // Had to reintroduce to support the old PHP7 client
27+
BOOL = 17
28+
HLL = 18
29+
MAP = 19
30+
LIST = 20
31+
LDT = 21
32+
GEOJSON = 23
3233
//revive:enable
3334
)

unpacker.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package aerospike
1616

1717
import (
18+
"bytes"
1819
"fmt"
1920
"math"
2021
"reflect"
@@ -232,6 +233,29 @@ func (upckr *unpacker) unpackBlob(count int, isMapKey bool) (interface{}, Error)
232233
case ParticleType.GEOJSON:
233234
val = NewGeoJSONValue(string(upckr.buffer[upckr.offset : upckr.offset+count]))
234235

236+
case ParticleType.PHP_BLOB:
237+
PHP_BLOB_PARSER:
238+
switch count {
239+
case 4:
240+
if bytes.Equal(upckr.buffer[upckr.offset:upckr.offset+count], []byte{0x62, 0x3A, 0x31, 0x3B}) {
241+
val = true
242+
break PHP_BLOB_PARSER
243+
} else if bytes.Equal(upckr.buffer[upckr.offset:upckr.offset+count], []byte{0x62, 0x3A, 0x30, 0x3B}) {
244+
val = false
245+
break PHP_BLOB_PARSER
246+
}
247+
fallthrough
248+
case 2:
249+
if bytes.Equal(upckr.buffer[upckr.offset:upckr.offset+count], []byte{0x4E, 0x3B}) {
250+
val = nil
251+
break PHP_BLOB_PARSER
252+
}
253+
fallthrough
254+
default:
255+
newObj := make([]byte, count)
256+
copy(newObj, upckr.buffer[upckr.offset:upckr.offset+count])
257+
val = newObj
258+
}
235259
default:
236260
return nil, newError(types.PARSE_ERROR, fmt.Sprintf("Error while unpacking BLOB. Type-header with code `%d` not recognized.", theType))
237261
}

value.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package aerospike
1616

1717
import (
18+
"bytes"
1819
"fmt"
1920
"reflect"
2021
"strconv"
@@ -1247,6 +1248,22 @@ func bytesToParticle(ptype int, buf []byte, offset int, length int) (interface{}
12471248
case ParticleType.LDT:
12481249
return newUnpacker(buf, offset, length).unpackObjects()
12491250

1251+
case ParticleType.PHP_BLOB:
1252+
if length == 4 {
1253+
if bytes.Equal(buf[offset:offset+length], []byte{0x62, 0x3A, 0x31, 0x3B}) {
1254+
return true, nil
1255+
} else if bytes.Equal(buf[offset:offset+length], []byte{0x62, 0x3A, 0x30, 0x3B}) {
1256+
return false, nil
1257+
}
1258+
} else if length == 2 {
1259+
if bytes.Equal(buf[offset:offset+length], []byte{0x4E, 0x3B}) {
1260+
return nil, nil
1261+
}
1262+
}
1263+
// generic PHP_BLOB
1264+
newObj := make([]byte, length)
1265+
copy(newObj, buf[offset:offset+length])
1266+
return newObj, nil
12501267
}
12511268
return nil, nil
12521269
}

0 commit comments

Comments
 (0)