aerospike / aerospike-client-go

Aerospike Client Go
Apache License 2.0
432 stars 198 forks source link

Adding a KV pair to a map where the value is a struct. #276

Closed phasetri closed 4 years ago

phasetri commented 4 years ago

Hello again

I have a record in the database where one of the bins (i.e. Passengers) is a map:

aql> select Passengers from  test.Sandbox
MAP(
'{"Joe":{"Name":"Joe", "Nationality":"American"},
  "Sam":{"Name":"Sam", "Nationality":"Canadian"}}') 

Using the MapPutOp function, I can append simple KV pairs to the map, such {Nick: 2}. However, if try appending a KV pair where the value is a struct:

Key: "Nick"
Value: &asc.Passenger{Name:"Nick", Nationality:"Brazilian"}

I encounter a packing error:

panic: Type `&asc.Passenger{Name:"Nick", Nationality:"Brazilian"}` not supported to pack. [recovered]
    panic: Type `&asc.Passenger{Name:"Nick", Nationality:"Brazilian"}` not supported to pack.

goroutine 60 [running]:
testing.tRunner.func1(0xc000206200)
    c:/go/src/testing/testing.go:874 +0x3aa
panic(0x7a2080, 0xc000054980)
    c:/go/src/runtime/panic.go:679 +0x1c0
github.com/aerospike/aerospike-client-go.concretePackObjectReflect(0x0, 0x0, 0x78c580, 0xc000004640, 0x0, 0x0, 0x0, 0xc00019f638)
    C:/Users/naf/go/src/github.com/aerospike/aerospike-client-go/packer_reflect.go:74 +0xeff

Is there a way to get around this? I looked through cdt_map_test.go but haven't seen any examples of appending struct values to a map.

phasetri commented 4 years ago

I can confirm that MapPutOp works at least with map-type values; I can just marshal the struct into a map.

mariaefi29 commented 4 years ago

Dear @phasetri,

Do I understand right that it is impossible to use MapPutOp in this case? What do you use instead now to update a value of the map by a key?

Would be very grateful for your reply!

phasetri commented 4 years ago

I still use MapPutOp for this case. MapPutOp works out-of-the-box when setting primitive values like int, string, and float. But when you want to set a map value to a non-primitive value like a Struct, you need to convert the struct into a map before passing it to MapPutOp.

mariaefi29 commented 4 years ago

Thank you for your reply! We have decided that in our case it is ok to use GetObject (with aerospike tags as), update a map as you want, and put it back with PutObject. At least for now :)