1// Copyright 2013-2020 Aerospike, Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package aerospike 16 17import ( 18 "fmt" 19 "reflect" 20 "strconv" 21 22 ParticleType "github.com/aerospike/aerospike-client-go/internal/particle_type" 23 . "github.com/aerospike/aerospike-client-go/types" 24 Buffer "github.com/aerospike/aerospike-client-go/utils/buffer" 25) 26 27// this function will be set in value_slow file if included 28var newValueReflect func(interface{}) Value 29 30// Map pair is used when the client returns sorted maps from the server 31// Since the default map in Go is a hash map, we will use a slice 32// to return the results in server order 33type MapPair struct{ Key, Value interface{} } 34 35// Value interface is used to efficiently serialize objects into the wire protocol. 36type Value interface { 37 38 // Calculate number of vl.bytes necessary to serialize the value in the wire protocol. 39 EstimateSize() (int, error) 40 41 // Serialize the value in the wire protocol. 42 write(cmd BufferEx) (int, error) 43 44 // Serialize the value using MessagePack. 45 pack(cmd BufferEx) (int, error) 46 47 // GetType returns wire protocol value type. 48 GetType() int 49 50 // GetObject returns original value as an interface{}. 51 GetObject() interface{} 52 53 // String implements Stringer interface. 54 String() string 55} 56 57type AerospikeBlob interface { 58 // EncodeBlob returns a byte slice representing the encoding of the 59 // receiver for transmission to a Decoder, usually of the same 60 // concrete type. 61 EncodeBlob() ([]byte, error) 62} 63 64// tryConcreteValue will return an aerospike value. 65// If the encoder does not exist, it will not try to use reflection. 66func tryConcreteValue(v interface{}) Value { 67 switch val := v.(type) { 68 case Value: 69 return val 70 case int: 71 return IntegerValue(val) 72 case int64: 73 return LongValue(val) 74 case string: 75 return StringValue(val) 76 case []interface{}: 77 return ListValue(val) 78 case map[string]interface{}: 79 return JsonValue(val) 80 case map[interface{}]interface{}: 81 return NewMapValue(val) 82 case nil: 83 return nullValue 84 case []Value: 85 return NewValueArray(val) 86 case []byte: 87 return BytesValue(val) 88 case int8: 89 return IntegerValue(int(val)) 90 case int16: 91 return IntegerValue(int(val)) 92 case int32: 93 return IntegerValue(int(val)) 94 case uint8: // byte supported here 95 return IntegerValue(int(val)) 96 case uint16: 97 return IntegerValue(int(val)) 98 case uint32: 99 return IntegerValue(int(val)) 100 case float32: 101 return FloatValue(float64(val)) 102 case float64: 103 return FloatValue(val) 104 case uint: 105 // if it doesn't overflow int64, it is OK 106 if int64(val) >= 0 { 107 return LongValue(int64(val)) 108 } 109 case MapIter: 110 return NewMapperValue(val) 111 case ListIter: 112 return NewListerValue(val) 113 case AerospikeBlob: 114 return NewBlobValue(val) 115 116 /* 117 The following cases will try to avoid using reflection by matching against the 118 internal generic types. 119 If you have custom type aliases in your code, you can use the same aerospike types to cast your type into, 120 to avoid hitting the reflection. 121 */ 122 case []string: 123 return NewListerValue(stringSlice(val)) 124 case []int: 125 return NewListerValue(intSlice(val)) 126 case []int8: 127 return NewListerValue(int8Slice(val)) 128 case []int16: 129 return NewListerValue(int16Slice(val)) 130 case []int32: 131 return NewListerValue(int32Slice(val)) 132 case []int64: 133 return NewListerValue(int64Slice(val)) 134 case []uint16: 135 return NewListerValue(uint16Slice(val)) 136 case []uint32: 137 return NewListerValue(uint32Slice(val)) 138 case []uint64: 139 return NewListerValue(uint64Slice(val)) 140 case []float32: 141 return NewListerValue(float32Slice(val)) 142 case []float64: 143 return NewListerValue(float64Slice(val)) 144 case map[string]string: 145 return NewMapperValue(stringStringMap(val)) 146 case map[string]int: 147 return NewMapperValue(stringIntMap(val)) 148 case map[string]int8: 149 return NewMapperValue(stringInt8Map(val)) 150 case map[string]int16: 151 return NewMapperValue(stringInt16Map(val)) 152 case map[string]int32: 153 return NewMapperValue(stringInt32Map(val)) 154 case map[string]int64: 155 return NewMapperValue(stringInt64Map(val)) 156 case map[string]uint16: 157 return NewMapperValue(stringUint16Map(val)) 158 case map[string]uint32: 159 return NewMapperValue(stringUint32Map(val)) 160 case map[string]float32: 161 return NewMapperValue(stringFloat32Map(val)) 162 case map[string]float64: 163 return NewMapperValue(stringFloat64Map(val)) 164 case map[int]string: 165 return NewMapperValue(intStringMap(val)) 166 case map[int]int: 167 return NewMapperValue(intIntMap(val)) 168 case map[int]int8: 169 return NewMapperValue(intInt8Map(val)) 170 case map[int]int16: 171 return NewMapperValue(intInt16Map(val)) 172 case map[int]int32: 173 return NewMapperValue(intInt32Map(val)) 174 case map[int]int64: 175 return NewMapperValue(intInt64Map(val)) 176 case map[int]uint16: 177 return NewMapperValue(intUint16Map(val)) 178 case map[int]uint32: 179 return NewMapperValue(intUint32Map(val)) 180 case map[int]float32: 181 return NewMapperValue(intFloat32Map(val)) 182 case map[int]float64: 183 return NewMapperValue(intFloat64Map(val)) 184 case map[int]interface{}: 185 return NewMapperValue(intInterfaceMap(val)) 186 case map[int8]string: 187 return NewMapperValue(int8StringMap(val)) 188 case map[int8]int: 189 return NewMapperValue(int8IntMap(val)) 190 case map[int8]int8: 191 return NewMapperValue(int8Int8Map(val)) 192 case map[int8]int16: 193 return NewMapperValue(int8Int16Map(val)) 194 case map[int8]int32: 195 return NewMapperValue(int8Int32Map(val)) 196 case map[int8]int64: 197 return NewMapperValue(int8Int64Map(val)) 198 case map[int8]uint16: 199 return NewMapperValue(int8Uint16Map(val)) 200 case map[int8]uint32: 201 return NewMapperValue(int8Uint32Map(val)) 202 case map[int8]float32: 203 return NewMapperValue(int8Float32Map(val)) 204 case map[int8]float64: 205 return NewMapperValue(int8Float64Map(val)) 206 case map[int8]interface{}: 207 return NewMapperValue(int8InterfaceMap(val)) 208 case map[int16]string: 209 return NewMapperValue(int16StringMap(val)) 210 case map[int16]int: 211 return NewMapperValue(int16IntMap(val)) 212 case map[int16]int8: 213 return NewMapperValue(int16Int8Map(val)) 214 case map[int16]int16: 215 return NewMapperValue(int16Int16Map(val)) 216 case map[int16]int32: 217 return NewMapperValue(int16Int32Map(val)) 218 case map[int16]int64: 219 return NewMapperValue(int16Int64Map(val)) 220 case map[int16]uint16: 221 return NewMapperValue(int16Uint16Map(val)) 222 case map[int16]uint32: 223 return NewMapperValue(int16Uint32Map(val)) 224 case map[int16]float32: 225 return NewMapperValue(int16Float32Map(val)) 226 case map[int16]float64: 227 return NewMapperValue(int16Float64Map(val)) 228 case map[int16]interface{}: 229 return NewMapperValue(int16InterfaceMap(val)) 230 case map[int32]string: 231 return NewMapperValue(int32StringMap(val)) 232 case map[int32]int: 233 return NewMapperValue(int32IntMap(val)) 234 case map[int32]int8: 235 return NewMapperValue(int32Int8Map(val)) 236 case map[int32]int16: 237 return NewMapperValue(int32Int16Map(val)) 238 case map[int32]int32: 239 return NewMapperValue(int32Int32Map(val)) 240 case map[int32]int64: 241 return NewMapperValue(int32Int64Map(val)) 242 case map[int32]uint16: 243 return NewMapperValue(int32Uint16Map(val)) 244 case map[int32]uint32: 245 return NewMapperValue(int32Uint32Map(val)) 246 case map[int32]float32: 247 return NewMapperValue(int32Float32Map(val)) 248 case map[int32]float64: 249 return NewMapperValue(int32Float64Map(val)) 250 case map[int32]interface{}: 251 return NewMapperValue(int32InterfaceMap(val)) 252 case map[int64]string: 253 return NewMapperValue(int64StringMap(val)) 254 case map[int64]int: 255 return NewMapperValue(int64IntMap(val)) 256 case map[int64]int8: 257 return NewMapperValue(int64Int8Map(val)) 258 case map[int64]int16: 259 return NewMapperValue(int64Int16Map(val)) 260 case map[int64]int32: 261 return NewMapperValue(int64Int32Map(val)) 262 case map[int64]int64: 263 return NewMapperValue(int64Int64Map(val)) 264 case map[int64]uint16: 265 return NewMapperValue(int64Uint16Map(val)) 266 case map[int64]uint32: 267 return NewMapperValue(int64Uint32Map(val)) 268 case map[int64]float32: 269 return NewMapperValue(int64Float32Map(val)) 270 case map[int64]float64: 271 return NewMapperValue(int64Float64Map(val)) 272 case map[int64]interface{}: 273 return NewMapperValue(int64InterfaceMap(val)) 274 case map[uint16]string: 275 return NewMapperValue(uint16StringMap(val)) 276 case map[uint16]int: 277 return NewMapperValue(uint16IntMap(val)) 278 case map[uint16]int8: 279 return NewMapperValue(uint16Int8Map(val)) 280 case map[uint16]int16: 281 return NewMapperValue(uint16Int16Map(val)) 282 case map[uint16]int32: 283 return NewMapperValue(uint16Int32Map(val)) 284 case map[uint16]int64: 285 return NewMapperValue(uint16Int64Map(val)) 286 case map[uint16]uint16: 287 return NewMapperValue(uint16Uint16Map(val)) 288 case map[uint16]uint32: 289 return NewMapperValue(uint16Uint32Map(val)) 290 case map[uint16]float32: 291 return NewMapperValue(uint16Float32Map(val)) 292 case map[uint16]float64: 293 return NewMapperValue(uint16Float64Map(val)) 294 case map[uint16]interface{}: 295 return NewMapperValue(uint16InterfaceMap(val)) 296 case map[uint32]string: 297 return NewMapperValue(uint32StringMap(val)) 298 case map[uint32]int: 299 return NewMapperValue(uint32IntMap(val)) 300 case map[uint32]int8: 301 return NewMapperValue(uint32Int8Map(val)) 302 case map[uint32]int16: 303 return NewMapperValue(uint32Int16Map(val)) 304 case map[uint32]int32: 305 return NewMapperValue(uint32Int32Map(val)) 306 case map[uint32]int64: 307 return NewMapperValue(uint32Int64Map(val)) 308 case map[uint32]uint16: 309 return NewMapperValue(uint32Uint16Map(val)) 310 case map[uint32]uint32: 311 return NewMapperValue(uint32Uint32Map(val)) 312 case map[uint32]float32: 313 return NewMapperValue(uint32Float32Map(val)) 314 case map[uint32]float64: 315 return NewMapperValue(uint32Float64Map(val)) 316 case map[uint32]interface{}: 317 return NewMapperValue(uint32InterfaceMap(val)) 318 case map[float32]string: 319 return NewMapperValue(float32StringMap(val)) 320 case map[float32]int: 321 return NewMapperValue(float32IntMap(val)) 322 case map[float32]int8: 323 return NewMapperValue(float32Int8Map(val)) 324 case map[float32]int16: 325 return NewMapperValue(float32Int16Map(val)) 326 case map[float32]int32: 327 return NewMapperValue(float32Int32Map(val)) 328 case map[float32]int64: 329 return NewMapperValue(float32Int64Map(val)) 330 case map[float32]uint16: 331 return NewMapperValue(float32Uint16Map(val)) 332 case map[float32]uint32: 333 return NewMapperValue(float32Uint32Map(val)) 334 case map[float32]float32: 335 return NewMapperValue(float32Float32Map(val)) 336 case map[float32]float64: 337 return NewMapperValue(float32Float64Map(val)) 338 case map[float32]interface{}: 339 return NewMapperValue(float32InterfaceMap(val)) 340 case map[float64]string: 341 return NewMapperValue(float64StringMap(val)) 342 case map[float64]int: 343 return NewMapperValue(float64IntMap(val)) 344 case map[float64]int8: 345 return NewMapperValue(float64Int8Map(val)) 346 case map[float64]int16: 347 return NewMapperValue(float64Int16Map(val)) 348 case map[float64]int32: 349 return NewMapperValue(float64Int32Map(val)) 350 case map[float64]int64: 351 return NewMapperValue(float64Int64Map(val)) 352 case map[float64]uint16: 353 return NewMapperValue(float64Uint16Map(val)) 354 case map[float64]uint32: 355 return NewMapperValue(float64Uint32Map(val)) 356 case map[float64]float32: 357 return NewMapperValue(float64Float32Map(val)) 358 case map[float64]float64: 359 return NewMapperValue(float64Float64Map(val)) 360 case map[float64]interface{}: 361 return NewMapperValue(float64InterfaceMap(val)) 362 case map[string]uint64: 363 return NewMapperValue(stringUint64Map(val)) 364 case map[int]uint64: 365 return NewMapperValue(intUint64Map(val)) 366 case map[int8]uint64: 367 return NewMapperValue(int8Uint64Map(val)) 368 case map[int16]uint64: 369 return NewMapperValue(int16Uint64Map(val)) 370 case map[int32]uint64: 371 return NewMapperValue(int32Uint64Map(val)) 372 case map[int64]uint64: 373 return NewMapperValue(int64Uint64Map(val)) 374 case map[uint16]uint64: 375 return NewMapperValue(uint16Uint64Map(val)) 376 case map[uint32]uint64: 377 return NewMapperValue(uint32Uint64Map(val)) 378 case map[float32]uint64: 379 return NewMapperValue(float32Uint64Map(val)) 380 case map[float64]uint64: 381 return NewMapperValue(float64Uint64Map(val)) 382 case map[uint64]string: 383 return NewMapperValue(uint64StringMap(val)) 384 case map[uint64]int: 385 return NewMapperValue(uint64IntMap(val)) 386 case map[uint64]int8: 387 return NewMapperValue(uint64Int8Map(val)) 388 case map[uint64]int16: 389 return NewMapperValue(uint64Int16Map(val)) 390 case map[uint64]int32: 391 return NewMapperValue(uint64Int32Map(val)) 392 case map[uint64]int64: 393 return NewMapperValue(uint64Int64Map(val)) 394 case map[uint64]uint16: 395 return NewMapperValue(uint64Uint16Map(val)) 396 case map[uint64]uint32: 397 return NewMapperValue(uint64Uint32Map(val)) 398 case map[uint64]uint64: 399 return NewMapperValue(uint64Uint64Map(val)) 400 case map[uint64]float32: 401 return NewMapperValue(uint64Float32Map(val)) 402 case map[uint64]float64: 403 return NewMapperValue(uint64Float64Map(val)) 404 case map[uint64]interface{}: 405 return NewMapperValue(uint64InterfaceMap(val)) 406 } 407 408 return nil 409} 410 411// NewValue generates a new Value object based on the type. 412// If the type is not supported, NewValue will panic. 413// This method is a convenience method, and should not be used 414// when absolute performance is required unless for the reason mentioned below. 415// 416// If you have custom maps or slices like: 417// type MyMap map[primitive1]primitive2, eg: map[int]string 418// or 419// type MySlice []primitive, eg: []float64 420// cast them to their primitive type when passing them to this method: 421// v := NewValue(map[int]string(myVar)) 422// v := NewValue([]float64(myVar)) 423// This way you will avoid hitting reflection. 424// To completely avoid reflection in the library, 425// use the build tag: as_performance while building your program. 426func NewValue(v interface{}) Value { 427 if value := tryConcreteValue(v); value != nil { 428 return value 429 } 430 431 if newValueReflect != nil { 432 if res := newValueReflect(v); res != nil { 433 return res 434 } 435 } 436 437 // panic for anything that is not supported. 438 panic(NewAerospikeError(TYPE_NOT_SUPPORTED, fmt.Sprintf("Value type '%v' (%s) not supported (if you are compiling via 'as_performance' tag, use cast either to primitives, or use ListIter or MapIter interfaces.)", v, reflect.TypeOf(v).String()))) 439} 440 441// NullValue is an empty value. 442type NullValue struct{} 443 444var nullValue NullValue 445 446// NewNullValue generates a NullValue instance. 447func NewNullValue() NullValue { 448 return nullValue 449} 450 451func (vl NullValue) EstimateSize() (int, error) { 452 return 0, nil 453} 454 455func (vl NullValue) write(cmd BufferEx) (int, error) { 456 return 0, nil 457} 458 459func (vl NullValue) pack(cmd BufferEx) (int, error) { 460 return packNil(cmd) 461} 462 463// GetType returns wire protocol value type. 464func (vl NullValue) GetType() int { 465 return ParticleType.NULL 466} 467 468// GetObject returns original value as an interface{}. 469func (vl NullValue) GetObject() interface{} { 470 return nil 471} 472 473func (vl NullValue) String() string { 474 return "" 475} 476 477/////////////////////////////////////////////////////////////////////////////// 478 479// InfinityValue is an empty value. 480type InfinityValue struct{} 481 482var infinityValue InfinityValue 483 484// NewInfinityValue generates a InfinityValue instance. 485func NewInfinityValue() InfinityValue { 486 return infinityValue 487} 488 489func (vl InfinityValue) EstimateSize() (int, error) { 490 return 0, nil 491} 492 493func (vl InfinityValue) write(cmd BufferEx) (int, error) { 494 return 0, nil 495} 496 497func (vl InfinityValue) pack(cmd BufferEx) (int, error) { 498 return packInfinity(cmd) 499} 500 501// GetType returns wire protocol value type. 502func (vl InfinityValue) GetType() int { 503 panic("Invalid particle type: INF") 504} 505 506// GetObject returns original value as an interface{}. 507func (vl InfinityValue) GetObject() interface{} { 508 return nil 509} 510 511func (vl InfinityValue) String() string { 512 return "INF" 513} 514 515/////////////////////////////////////////////////////////////////////////////// 516 517// InfinityValue is an empty value. 518type WildCardValue struct{} 519 520var wildCardValue WildCardValue 521 522// NewWildCardValue generates a WildCardValue instance. 523func NewWildCardValue() WildCardValue { 524 return wildCardValue 525} 526 527func (vl WildCardValue) EstimateSize() (int, error) { 528 return 0, nil 529} 530 531func (vl WildCardValue) write(cmd BufferEx) (int, error) { 532 return 0, nil 533} 534 535func (vl WildCardValue) pack(cmd BufferEx) (int, error) { 536 return packWildCard(cmd) 537} 538 539// GetType returns wire protocol value type. 540func (vl WildCardValue) GetType() int { 541 panic("Invalid particle type: WildCard") 542} 543 544// GetObject returns original value as an interface{}. 545func (vl WildCardValue) GetObject() interface{} { 546 return nil 547} 548 549func (vl WildCardValue) String() string { 550 return "*" 551} 552 553/////////////////////////////////////////////////////////////////////////////// 554 555// BytesValue encapsulates an array of bytes. 556type BytesValue []byte 557 558// NewBytesValue generates a ByteValue instance. 559func NewBytesValue(bytes []byte) BytesValue { 560 return BytesValue(bytes) 561} 562 563// NewBlobValue accepts an AerospikeBlob interface, and automatically 564// converts it to a BytesValue. 565// If Encode returns an err, it will panic. 566func NewBlobValue(object AerospikeBlob) BytesValue { 567 buf, err := object.EncodeBlob() 568 if err != nil { 569 panic(err) 570 } 571 572 return NewBytesValue(buf) 573} 574 575func (vl BytesValue) EstimateSize() (int, error) { 576 return len(vl), nil 577} 578 579func (vl BytesValue) write(cmd BufferEx) (int, error) { 580 return cmd.Write(vl) 581} 582 583func (vl BytesValue) pack(cmd BufferEx) (int, error) { 584 return packBytes(cmd, vl) 585} 586 587// GetType returns wire protocol value type. 588func (vl BytesValue) GetType() int { 589 return ParticleType.BLOB 590} 591 592// GetObject returns original value as an interface{}. 593func (vl BytesValue) GetObject() interface{} { 594 return []byte(vl) 595} 596 597// String implements Stringer interface. 598func (vl BytesValue) String() string { 599 return Buffer.BytesToHexString(vl) 600} 601 602/////////////////////////////////////////////////////////////////////////////// 603 604// StringValue encapsulates a string value. 605type StringValue string 606 607// NewStringValue generates a StringValue instance. 608func NewStringValue(value string) StringValue { 609 return StringValue(value) 610} 611 612func (vl StringValue) EstimateSize() (int, error) { 613 return len(vl), nil 614} 615 616func (vl StringValue) write(cmd BufferEx) (int, error) { 617 return cmd.WriteString(string(vl)) 618} 619 620func (vl StringValue) pack(cmd BufferEx) (int, error) { 621 return packString(cmd, string(vl)) 622} 623 624// GetType returns wire protocol value type. 625func (vl StringValue) GetType() int { 626 return ParticleType.STRING 627} 628 629// GetObject returns original value as an interface{}. 630func (vl StringValue) GetObject() interface{} { 631 return string(vl) 632} 633 634// String implements Stringer interface. 635func (vl StringValue) String() string { 636 return string(vl) 637} 638 639/////////////////////////////////////////////////////////////////////////////// 640 641// IntegerValue encapsulates an integer value. 642type IntegerValue int 643 644// NewIntegerValue generates an IntegerValue instance. 645func NewIntegerValue(value int) IntegerValue { 646 return IntegerValue(value) 647} 648 649func (vl IntegerValue) EstimateSize() (int, error) { 650 return 8, nil 651} 652 653func (vl IntegerValue) write(cmd BufferEx) (int, error) { 654 return cmd.WriteInt64(int64(vl)) 655} 656 657func (vl IntegerValue) pack(cmd BufferEx) (int, error) { 658 return packAInt64(cmd, int64(vl)) 659} 660 661// GetType returns wire protocol value type. 662func (vl IntegerValue) GetType() int { 663 return ParticleType.INTEGER 664} 665 666// GetObject returns original value as an interface{}. 667func (vl IntegerValue) GetObject() interface{} { 668 return int(vl) 669} 670 671// String implements Stringer interface. 672func (vl IntegerValue) String() string { 673 return strconv.Itoa(int(vl)) 674} 675 676/////////////////////////////////////////////////////////////////////////////// 677 678// LongValue encapsulates an int64 value. 679type LongValue int64 680 681// NewLongValue generates a LongValue instance. 682func NewLongValue(value int64) LongValue { 683 return LongValue(value) 684} 685 686func (vl LongValue) EstimateSize() (int, error) { 687 return 8, nil 688} 689 690func (vl LongValue) write(cmd BufferEx) (int, error) { 691 return cmd.WriteInt64(int64(vl)) 692} 693 694func (vl LongValue) pack(cmd BufferEx) (int, error) { 695 return packAInt64(cmd, int64(vl)) 696} 697 698// GetType returns wire protocol value type. 699func (vl LongValue) GetType() int { 700 return ParticleType.INTEGER 701} 702 703// GetObject returns original value as an interface{}. 704func (vl LongValue) GetObject() interface{} { 705 return int64(vl) 706} 707 708// String implements Stringer interface. 709func (vl LongValue) String() string { 710 return strconv.Itoa(int(vl)) 711} 712 713/////////////////////////////////////////////////////////////////////////////// 714 715// FloatValue encapsulates an float64 value. 716type FloatValue float64 717 718// NewFloatValue generates a FloatValue instance. 719func NewFloatValue(value float64) FloatValue { 720 return FloatValue(value) 721} 722 723func (vl FloatValue) EstimateSize() (int, error) { 724 return 8, nil 725} 726 727func (vl FloatValue) write(cmd BufferEx) (int, error) { 728 return cmd.WriteFloat64(float64(vl)) 729} 730 731func (vl FloatValue) pack(cmd BufferEx) (int, error) { 732 return packFloat64(cmd, float64(vl)) 733} 734 735// GetType returns wire protocol value type. 736func (vl FloatValue) GetType() int { 737 return ParticleType.FLOAT 738} 739 740// GetObject returns original value as an interface{}. 741func (vl FloatValue) GetObject() interface{} { 742 return float64(vl) 743} 744 745// String implements Stringer interface. 746func (vl FloatValue) String() string { 747 return (fmt.Sprintf("%f", vl)) 748} 749 750/////////////////////////////////////////////////////////////////////////////// 751 752// _BoolValue encapsulates a bool value. 753// This method is only used in bitwise CDT operations internally. 754type _BoolValue bool 755 756func (vb _BoolValue) EstimateSize() (int, error) { 757 return PackBool(nil, bool(vb)) 758} 759 760func (vb _BoolValue) write(cmd BufferEx) (int, error) { 761 panic("Unreachable") 762} 763 764func (vb _BoolValue) pack(cmd BufferEx) (int, error) { 765 return PackBool(cmd, bool(vb)) 766} 767 768// GetType returns wire protocol value type. 769func (vb _BoolValue) GetType() int { 770 panic("Unreachable") 771} 772 773// GetObject returns original value as an interface{}. 774func (vb _BoolValue) GetObject() interface{} { 775 return bool(vb) 776} 777 778// String implements Stringer interface. 779func (vb _BoolValue) String() string { 780 return (fmt.Sprintf("%v", bool(vb))) 781} 782 783/////////////////////////////////////////////////////////////////////////////// 784 785// ValueArray encapsulates an array of Value. 786// Supported by Aerospike 3+ servers only. 787type ValueArray []Value 788 789// NewValueArray generates a ValueArray instance. 790func NewValueArray(array []Value) *ValueArray { 791 // return &ValueArray{*NewListerValue(valueList(array))} 792 res := ValueArray(array) 793 return &res 794} 795 796func (va ValueArray) EstimateSize() (int, error) { 797 return packValueArray(nil, va) 798} 799 800func (va ValueArray) write(cmd BufferEx) (int, error) { 801 return packValueArray(cmd, va) 802} 803 804func (va ValueArray) pack(cmd BufferEx) (int, error) { 805 return packValueArray(cmd, []Value(va)) 806} 807 808// GetType returns wire protocol value type. 809func (va ValueArray) GetType() int { 810 return ParticleType.LIST 811} 812 813// GetObject returns original value as an interface{}. 814func (va ValueArray) GetObject() interface{} { 815 return []Value(va) 816} 817 818// String implements Stringer interface. 819func (va ValueArray) String() string { 820 return fmt.Sprintf("%v", []Value(va)) 821} 822 823/////////////////////////////////////////////////////////////////////////////// 824 825// ListValue encapsulates any arbitrary array. 826// Supported by Aerospike 3+ servers only. 827type ListValue []interface{} 828 829// NewListValue generates a ListValue instance. 830func NewListValue(list []interface{}) ListValue { 831 return ListValue(list) 832} 833 834func (vl ListValue) EstimateSize() (int, error) { 835 return packIfcList(nil, vl) 836} 837 838func (vl ListValue) write(cmd BufferEx) (int, error) { 839 return packIfcList(cmd, vl) 840} 841 842func (vl ListValue) pack(cmd BufferEx) (int, error) { 843 return packIfcList(cmd, []interface{}(vl)) 844} 845 846// GetType returns wire protocol value type. 847func (vl ListValue) GetType() int { 848 return ParticleType.LIST 849} 850 851// GetObject returns original value as an interface{}. 852func (vl ListValue) GetObject() interface{} { 853 return []interface{}(vl) 854} 855 856// String implements Stringer interface. 857func (vl ListValue) String() string { 858 return fmt.Sprintf("%v", []interface{}(vl)) 859} 860 861/////////////////////////////////////////////////////////////////////////////// 862 863// ListerValue encapsulates any arbitrary array. 864// Supported by Aerospike 3+ servers only. 865type ListerValue struct { 866 list ListIter 867} 868 869// NewListValue generates a ListValue instance. 870func NewListerValue(list ListIter) *ListerValue { 871 res := &ListerValue{ 872 list: list, 873 } 874 875 return res 876} 877 878func (vl *ListerValue) EstimateSize() (int, error) { 879 return packList(nil, vl.list) 880} 881 882func (vl *ListerValue) write(cmd BufferEx) (int, error) { 883 return packList(cmd, vl.list) 884} 885 886func (vl *ListerValue) pack(cmd BufferEx) (int, error) { 887 return packList(cmd, vl.list) 888} 889 890// GetType returns wire protocol value type. 891func (vl *ListerValue) GetType() int { 892 return ParticleType.LIST 893} 894 895// GetObject returns original value as an interface{}. 896func (vl *ListerValue) GetObject() interface{} { 897 return vl.list 898} 899 900// String implements Stringer interface. 901func (vl *ListerValue) String() string { 902 return fmt.Sprintf("%v", vl.list) 903} 904 905/////////////////////////////////////////////////////////////////////////////// 906 907// MapValue encapsulates an arbitrary map. 908// Supported by Aerospike 3+ servers only. 909type MapValue map[interface{}]interface{} 910 911// NewMapValue generates a MapValue instance. 912func NewMapValue(vmap map[interface{}]interface{}) MapValue { 913 return MapValue(vmap) 914} 915 916func (vl MapValue) EstimateSize() (int, error) { 917 return packIfcMap(nil, vl) 918} 919 920func (vl MapValue) write(cmd BufferEx) (int, error) { 921 return packIfcMap(cmd, vl) 922} 923 924func (vl MapValue) pack(cmd BufferEx) (int, error) { 925 return packIfcMap(cmd, vl) 926} 927 928// GetType returns wire protocol value type. 929func (vl MapValue) GetType() int { 930 return ParticleType.MAP 931} 932 933// GetObject returns original value as an interface{}. 934func (vl MapValue) GetObject() interface{} { 935 return map[interface{}]interface{}(vl) 936} 937 938func (vl MapValue) String() string { 939 return fmt.Sprintf("%v", map[interface{}]interface{}(vl)) 940} 941 942/////////////////////////////////////////////////////////////////////////////// 943 944// JsonValue encapsulates a Json map. 945// Supported by Aerospike 3+ servers only. 946type JsonValue map[string]interface{} 947 948// NewMapValue generates a JsonValue instance. 949func NewJsonValue(vmap map[string]interface{}) JsonValue { 950 return JsonValue(vmap) 951} 952 953func (vl JsonValue) EstimateSize() (int, error) { 954 return packJsonMap(nil, vl) 955} 956 957func (vl JsonValue) write(cmd BufferEx) (int, error) { 958 return packJsonMap(cmd, vl) 959} 960 961func (vl JsonValue) pack(cmd BufferEx) (int, error) { 962 return packJsonMap(cmd, vl) 963} 964 965// GetType returns wire protocol value type. 966func (vl JsonValue) GetType() int { 967 return ParticleType.MAP 968} 969 970// GetObject returns original value as an interface{}. 971func (vl JsonValue) GetObject() interface{} { 972 return map[string]interface{}(vl) 973} 974 975func (vl JsonValue) String() string { 976 return fmt.Sprintf("%v", map[string]interface{}(vl)) 977} 978 979/////////////////////////////////////////////////////////////////////////////// 980 981// MapperValue encapsulates an arbitrary map which implements a MapIter interface. 982// Supported by Aerospike 3+ servers only. 983type MapperValue struct { 984 vmap MapIter 985} 986 987// NewMapValue generates a MapperValue instance. 988func NewMapperValue(vmap MapIter) *MapperValue { 989 res := &MapperValue{ 990 vmap: vmap, 991 } 992 993 return res 994} 995 996func (vl *MapperValue) EstimateSize() (int, error) { 997 return packMap(nil, vl.vmap) 998} 999 1000func (vl *MapperValue) write(cmd BufferEx) (int, error) { 1001 return packMap(cmd, vl.vmap) 1002} 1003 1004func (vl *MapperValue) pack(cmd BufferEx) (int, error) { 1005 return packMap(cmd, vl.vmap) 1006} 1007 1008// GetType returns wire protocol value type. 1009func (vl *MapperValue) GetType() int { 1010 return ParticleType.MAP 1011} 1012 1013// GetObject returns original value as an interface{}. 1014func (vl *MapperValue) GetObject() interface{} { 1015 return vl.vmap 1016} 1017 1018func (vl *MapperValue) String() string { 1019 return fmt.Sprintf("%v", vl.vmap) 1020} 1021 1022/////////////////////////////////////////////////////////////////////////////// 1023 1024// GeoJSONValue encapsulates a 2D Geo point. 1025// Supported by Aerospike 3.6.1 servers and later only. 1026type GeoJSONValue string 1027 1028// NewMapValue generates a GeoJSONValue instance. 1029func NewGeoJSONValue(value string) GeoJSONValue { 1030 res := GeoJSONValue(value) 1031 return res 1032} 1033 1034func (vl GeoJSONValue) EstimateSize() (int, error) { 1035 // flags + ncells + jsonstr 1036 return 1 + 2 + len(string(vl)), nil 1037} 1038 1039func (vl GeoJSONValue) write(cmd BufferEx) (int, error) { 1040 cmd.WriteByte(0) // flags 1041 cmd.WriteByte(0) // flags 1042 cmd.WriteByte(0) // flags 1043 1044 return cmd.WriteString(string(vl)) 1045} 1046 1047func (vl GeoJSONValue) pack(cmd BufferEx) (int, error) { 1048 return packGeoJson(cmd, string(vl)) 1049} 1050 1051// GetType returns wire protocol value type. 1052func (vl GeoJSONValue) GetType() int { 1053 return ParticleType.GEOJSON 1054} 1055 1056// GetObject returns original value as an interface{}. 1057func (vl GeoJSONValue) GetObject() interface{} { 1058 return string(vl) 1059} 1060 1061// String implements Stringer interface. 1062func (vl GeoJSONValue) String() string { 1063 return string(vl) 1064} 1065 1066/////////////////////////////////////////////////////////////////////////////// 1067 1068// HLLValue encapsulates a HyperLogLog value. 1069type HLLValue []byte 1070 1071// NewHLLValue generates a ByteValue instance. 1072func NewHLLValue(bytes []byte) HLLValue { 1073 return HLLValue(bytes) 1074} 1075 1076func (vl HLLValue) EstimateSize() (int, error) { 1077 return len(vl), nil 1078} 1079 1080func (vl HLLValue) write(cmd BufferEx) (int, error) { 1081 return cmd.Write(vl) 1082} 1083 1084func (vl HLLValue) pack(cmd BufferEx) (int, error) { 1085 return packBytes(cmd, vl) 1086} 1087 1088// GetType returns wire protocol value type. 1089func (vl HLLValue) GetType() int { 1090 return ParticleType.HLL 1091} 1092 1093// GetObject returns original value as an interface{}. 1094func (vl HLLValue) GetObject() interface{} { 1095 return []byte(vl) 1096} 1097 1098// String implements Stringer interface. 1099func (vl HLLValue) String() string { 1100 return Buffer.BytesToHexString([]byte(vl)) 1101} 1102 1103////////////////////////////////////////////////////////////////////////////// 1104 1105func bytesToParticle(ptype int, buf []byte, offset int, length int) (interface{}, error) { 1106 1107 switch ptype { 1108 case ParticleType.INTEGER: 1109 // return `int` for 64bit platforms for compatibility reasons 1110 if Buffer.Arch64Bits { 1111 return int(Buffer.VarBytesToInt64(buf, offset, length)), nil 1112 } 1113 return Buffer.VarBytesToInt64(buf, offset, length), nil 1114 1115 case ParticleType.STRING: 1116 return string(buf[offset : offset+length]), nil 1117 1118 case ParticleType.FLOAT: 1119 return Buffer.BytesToFloat64(buf, offset), nil 1120 1121 case ParticleType.MAP: 1122 return newUnpacker(buf, offset, length).UnpackMap() 1123 1124 case ParticleType.LIST: 1125 return newUnpacker(buf, offset, length).UnpackList() 1126 1127 case ParticleType.GEOJSON: 1128 ncells := int(Buffer.BytesToInt16(buf, offset+1)) 1129 headerSize := 1 + 2 + (ncells * 8) 1130 return string(buf[offset+headerSize : offset+length]), nil 1131 1132 case ParticleType.HLL: 1133 newObj := make([]byte, length) 1134 copy(newObj, buf[offset:offset+length]) 1135 return newObj, nil 1136 1137 case ParticleType.BLOB: 1138 newObj := make([]byte, length) 1139 copy(newObj, buf[offset:offset+length]) 1140 return newObj, nil 1141 1142 case ParticleType.LDT: 1143 return newUnpacker(buf, offset, length).unpackObjects() 1144 1145 } 1146 return nil, nil 1147} 1148 1149func bytesToKeyValue(pType int, buf []byte, offset int, len int) (Value, error) { 1150 1151 switch pType { 1152 case ParticleType.STRING: 1153 return NewStringValue(string(buf[offset : offset+len])), nil 1154 1155 case ParticleType.INTEGER: 1156 return NewLongValue(Buffer.VarBytesToInt64(buf, offset, len)), nil 1157 1158 case ParticleType.FLOAT: 1159 return NewFloatValue(Buffer.BytesToFloat64(buf, offset)), nil 1160 1161 case ParticleType.BLOB: 1162 bytes := make([]byte, len, len) 1163 copy(bytes, buf[offset:offset+len]) 1164 return NewBytesValue(bytes), nil 1165 1166 default: 1167 return nil, NewAerospikeError(PARSE_ERROR, fmt.Sprintf("ParticleType %d not recognized. Please file a github issue.", pType)) 1168 } 1169} 1170 1171func unwrapValue(v interface{}) interface{} { 1172 if v == nil { 1173 return nil 1174 } 1175 1176 if uv, ok := v.(Value); ok { 1177 return unwrapValue(uv.GetObject()) 1178 } else if uv, ok := v.([]Value); ok { 1179 a := make([]interface{}, len(uv)) 1180 for i := range uv { 1181 a[i] = unwrapValue(uv[i].GetObject()) 1182 } 1183 return a 1184 } 1185 1186 return v 1187} 1188