1/*
2 * Copyright 2012-2020 Aerospike, Inc.
3 *
4 * Portions may be licensed to Aerospike, Inc. under one or more contributor
5 * license agreements.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8 * use this file except in compliance with the License. You may obtain a copy of
9 * the License at http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17
18package main
19
20import (
21	"bytes"
22	"log"
23
24	as "github.com/aerospike/aerospike-client-go"
25	shared "github.com/aerospike/aerospike-client-go/examples/shared"
26)
27
28func main() {
29	testListStrings(shared.Client)
30	testListComplex(shared.Client)
31	testMapStrings(shared.Client)
32	testMapComplex(shared.Client)
33	testListMapCombined(shared.Client)
34
35	log.Println("Example finished successfully.")
36}
37
38/**
39 * Write/Read []string directly instead of relying on java serializer.
40 */
41func testListStrings(client *as.Client) {
42	log.Printf("Read/Write []string")
43	key, _ := as.NewKey(*shared.Namespace, *shared.Set, "listkey1")
44	client.Delete(shared.WritePolicy, key)
45
46	list := []string{"string1", "string2", "string3"}
47
48	bin := as.NewBin("listbin1", list)
49	client.PutBins(shared.WritePolicy, key, bin)
50
51	record, err := client.Get(shared.Policy, key, bin.Name)
52	shared.PanicOnError(err)
53	receivedList := record.Bins[bin.Name].([]interface{})
54
55	validateSize(3, len(receivedList))
56	validate("string1", receivedList[0])
57	validate("string2", receivedList[1])
58	validate("string3", receivedList[2])
59
60	log.Printf("Read/Write []string successful.")
61}
62
63/**
64 * Write/Read []interface{} directly instead of relying on java serializer.
65 */
66func testListComplex(client *as.Client) {
67	log.Printf("Read/Write []interface{}")
68	key, _ := as.NewKey(*shared.Namespace, *shared.Set, "listkey2")
69	client.Delete(shared.WritePolicy, key)
70
71	blob := []byte{3, 52, 125}
72	list := []interface{}{"string1", 2, blob}
73
74	bin := as.NewBin("listbin2", list)
75	client.PutBins(shared.WritePolicy, key, bin)
76
77	record, err := client.Get(shared.Policy, key, bin.Name)
78	shared.PanicOnError(err)
79	receivedList := record.Bins[bin.Name].([]interface{})
80
81	validateSize(3, len(receivedList))
82	validate("string1", receivedList[0])
83	// Server convert numbers to long, so must expect long.
84	validate(2, receivedList[1])
85	validateBytes(blob, receivedList[2].([]byte))
86
87	log.Printf("Read/Write []interface{} successful.")
88}
89
90/**
91 * Write/Read map[string]string directly instead of relying on java serializer.
92 */
93func testMapStrings(client *as.Client) {
94	log.Printf("Read/Write map[string]string")
95	key, _ := as.NewKey(*shared.Namespace, *shared.Set, "mapkey1")
96	client.Delete(shared.WritePolicy, key)
97
98	amap := map[string]string{"key1": "string1",
99		"key2": "string2",
100		"key3": "string3",
101	}
102	bin := as.NewBin("mapbin1", amap)
103	client.PutBins(shared.WritePolicy, key, bin)
104
105	record, err := client.Get(shared.Policy, key, bin.Name)
106	shared.PanicOnError(err)
107	receivedMap := record.Bins[bin.Name].(map[interface{}]interface{})
108
109	validateSize(3, len(receivedMap))
110	validate("string1", receivedMap["key1"])
111	validate("string2", receivedMap["key2"])
112	validate("string3", receivedMap["key3"])
113
114	log.Printf("Read/Write map[string]string successful")
115}
116
117/**
118 * Write/Read map[interface{}]interface{} directly instead of relying on java serializer.
119 */
120func testMapComplex(client *as.Client) {
121	log.Printf("Read/Write map[interface{}]interface{}")
122	key, _ := as.NewKey(*shared.Namespace, *shared.Set, "mapkey2")
123	client.Delete(shared.WritePolicy, key)
124
125	blob := []byte{3, 52, 125}
126	list := []int{
127		100034,
128		12384955,
129		3,
130		512,
131	}
132
133	amap := map[interface{}]interface{}{
134		"key1": "string1",
135		"key2": 2,
136		"key3": blob,
137		"key4": list,
138	}
139
140	bin := as.NewBin("mapbin2", amap)
141	client.PutBins(shared.WritePolicy, key, bin)
142
143	record, err := client.Get(shared.Policy, key, bin.Name)
144	shared.PanicOnError(err)
145	receivedMap := record.Bins[bin.Name].(map[interface{}]interface{})
146
147	validateSize(4, len(receivedMap))
148	validate("string1", receivedMap["key1"])
149	// Server convert numbers to long, so must expect long.
150	validate(2, receivedMap["key2"])
151	validateBytes(blob, receivedMap["key3"].([]byte))
152
153	receivedInner := receivedMap["key4"].([]interface{})
154	validateSize(4, len(receivedInner))
155	validate(100034, receivedInner[0])
156	validate(12384955, receivedInner[1])
157	validate(3, receivedInner[2])
158	validate(512, receivedInner[3])
159
160	log.Printf("Read/Write map[interface{}]interface{} successful")
161}
162
163/**
164 * Write/Read Array/Map combination directly instead of relying on java serializer.
165 */
166func testListMapCombined(client *as.Client) {
167	log.Printf("Read/Write Array/Map")
168	key, _ := as.NewKey(*shared.Namespace, *shared.Set, "listmapkey")
169	client.Delete(shared.WritePolicy, key)
170
171	blob := []byte{3, 52, 125}
172	inner := []interface{}{
173		"string2",
174		5,
175	}
176
177	innerMap := map[interface{}]interface{}{
178		"a":    1,
179		2:      "b",
180		3:      blob,
181		"list": inner,
182	}
183
184	list := []interface{}{
185		"string1",
186		8,
187		inner,
188		innerMap,
189	}
190
191	bin := as.NewBin("listmapbin", list)
192	client.PutBins(shared.WritePolicy, key, bin)
193
194	record, err := client.Get(shared.Policy, key, bin.Name)
195	shared.PanicOnError(err)
196	received := record.Bins[bin.Name].([]interface{})
197
198	validateSize(4, len(received))
199	validate("string1", received[0])
200	// Server convert numbers to long, so must expect long.
201	validate(8, received[1])
202
203	receivedInner := received[2].([]interface{})
204	validateSize(2, len(receivedInner))
205	validate("string2", receivedInner[0])
206	validate(5, receivedInner[1])
207
208	receivedMap := received[3].(map[interface{}]interface{})
209	validateSize(4, len(receivedMap))
210	validate(1, receivedMap["a"])
211	validate("b", receivedMap[2])
212	validateBytes(blob, receivedMap[3].([]byte))
213
214	receivedInner2 := receivedMap["list"].([]interface{})
215	validateSize(2, len(receivedInner2))
216	validate("string2", receivedInner2[0])
217	validate(5, receivedInner2[1])
218
219	log.Printf("Read/Write Array/Map successful")
220}
221
222func validateSize(expected, received int) {
223	if received != expected {
224		log.Fatalf(
225			"Size mismatch: expected=%d received=%d", expected, received)
226	}
227}
228
229func validate(expected, received interface{}) {
230	if !(received == expected) {
231		log.Fatalf(
232			"Mismatch: expected=%v received=%v", expected, received)
233	}
234}
235
236func validateBytes(expected []byte, received []byte) {
237	if !bytes.Equal(expected, received) {
238		log.Fatalf(
239			"Mismatch: expected=%v received=%v", expected, received)
240	}
241}
242