aerospike 2.11.0 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +1 -1
- data/lib/aerospike/client.rb +0 -1
- data/lib/aerospike/command/batch_index_command.rb +10 -2
- data/lib/aerospike/command/command.rb +81 -7
- data/lib/aerospike/command/delete_command.rb +16 -4
- data/lib/aerospike/command/exists_command.rb +16 -4
- data/lib/aerospike/command/multi_command.rb +6 -3
- data/lib/aerospike/command/read_command.rb +24 -17
- data/lib/aerospike/command/read_header_command.rb +13 -5
- data/lib/aerospike/command/touch_command.rb +9 -2
- data/lib/aerospike/command/write_command.rb +8 -3
- data/lib/aerospike/operation.rb +5 -0
- data/lib/aerospike/policy/policy.rb +46 -1
- data/lib/aerospike/query/query_command.rb +6 -4
- data/lib/aerospike/query/statement.rb +8 -1
- data/lib/aerospike/result_code.rb +12 -6
- data/lib/aerospike/value/value.rb +58 -28
- data/lib/aerospike/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4509fc71b11809038c6ea0a8853e92de02fcade0f8e29723e7507a029f7a5e1
|
4
|
+
data.tar.gz: 8fd24ad2f984e728c9e6137b7bf6527aaa07a1371c9d46539de7f066048b13e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41aaaabe27c7f9a9080fb33a10444bef59f5ba6482b775d6b812529b3cc4f4656665a4e7294d328df3048c18519fafd99ac448b333c7a0506c78305a685c579e
|
7
|
+
data.tar.gz: adf16fbcb8247ac8724d1823a1072cf5796f52477fb5a9bbe84f17a6ad71402f33b3ba2db9777a8b907737d291b7e5d9a98fa6ec7595093c5fb2d0cf24915de8
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,20 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [
|
5
|
+
## [2.12.0] - 2019-04-21
|
6
|
+
|
7
|
+
* **New Features**
|
8
|
+
* Support for predicate expressions in all transaction.
|
9
|
+
* Support for `operation.delete` in `client#operate`.
|
10
|
+
|
11
|
+
* **Improvements**
|
12
|
+
* Optimize serialization for nested structures. Thanks to [@Kacper Madej](https://github.com/madejejej)! [[#94](https://github.com/aerospike/aerospike-client-ruby/pull/94)]
|
13
|
+
* Remove `Thread#abort_on_exception` from `batch_index_command`. Thanks to [@Kacper Madej](https://github.com/madejejej)! [[#94](https://github.com/aerospike/aerospike-client-ruby/pull/92)]
|
14
|
+
* Does not allow values other than Integer, Float, String, Symbol and nil to be used as keys in Maps.
|
15
|
+
|
16
|
+
* **Bug Fixes**
|
17
|
+
* Fixes tests that weren't using ENV variables for connections. This will allow the tests to be run on any server.
|
18
|
+
|
6
19
|
|
7
20
|
## [2.11.0] - 2019-05-17
|
8
21
|
|
data/README.md
CHANGED
@@ -97,7 +97,7 @@ This library is packaged with a number of tests.
|
|
97
97
|
|
98
98
|
To run all the test cases:
|
99
99
|
|
100
|
-
$ bundle exec rspec
|
100
|
+
$ AEROSPIKE_HOSTS="<host:port>[,<hoist:port>]" AEROSPIKE_USER="<user>" AEROSPIKE_PASSWORD="<pass>" bundle exec rspec
|
101
101
|
|
102
102
|
<a name="Examples"></a>
|
103
103
|
## Examples
|
data/lib/aerospike/client.rb
CHANGED
@@ -39,7 +39,12 @@ module Aerospike
|
|
39
39
|
def write_buffer
|
40
40
|
bin_name_size = 0
|
41
41
|
operation_count = 0
|
42
|
+
field_count_row = 1
|
42
43
|
field_count = 1
|
44
|
+
|
45
|
+
predexp_size = estimate_predexp(@policy.predexp)
|
46
|
+
field_count += 1 if predexp_size > 0
|
47
|
+
|
43
48
|
if bin_names
|
44
49
|
bin_names.each do |bin_name|
|
45
50
|
bin_name_size += bin_name.bytesize + OPERATION_HEADER_SIZE
|
@@ -61,7 +66,10 @@ module Aerospike
|
|
61
66
|
end
|
62
67
|
end
|
63
68
|
size_buffer
|
64
|
-
write_header(policy,read_attr | INFO1_BATCH, 0,
|
69
|
+
write_header(policy,read_attr | INFO1_BATCH, 0, field_count, 0)
|
70
|
+
|
71
|
+
write_predexp(@policy.predexp, predexp_size)
|
72
|
+
|
65
73
|
write_field_header(0, Aerospike::FieldType::BATCH_INDEX)
|
66
74
|
@data_offset += @data_buffer.write_int32(batch.keys.length, @data_offset)
|
67
75
|
@data_offset += @data_buffer.write_byte(1, @data_offset)
|
@@ -77,7 +85,7 @@ module Aerospike
|
|
77
85
|
else
|
78
86
|
@data_offset += @data_buffer.write_byte(0, @data_offset)
|
79
87
|
@data_offset += @data_buffer.write_byte(read_attr, @data_offset)
|
80
|
-
@data_offset += @data_buffer.write_int16(
|
88
|
+
@data_offset += @data_buffer.write_int16(field_count_row, @data_offset)
|
81
89
|
@data_offset += @data_buffer.write_int16(operation_count, @data_offset)
|
82
90
|
write_field_string(key.namespace, Aerospike::FieldType::NAMESPACE)
|
83
91
|
|
@@ -78,13 +78,16 @@ module Aerospike
|
|
78
78
|
class Command #:nodoc:
|
79
79
|
|
80
80
|
def initialize(node)
|
81
|
+
@data_offset = 0
|
82
|
+
@data_buffer = nil
|
83
|
+
|
81
84
|
@node = node
|
82
85
|
|
83
86
|
self
|
84
87
|
end
|
85
88
|
|
86
89
|
# List of all bins that this command will write to - sub-classes should
|
87
|
-
#
|
90
|
+
# override this as appropriate.
|
88
91
|
def write_bins
|
89
92
|
[]
|
90
93
|
end
|
@@ -93,6 +96,9 @@ module Aerospike
|
|
93
96
|
def set_write(policy, operation, key, bins)
|
94
97
|
begin_cmd
|
95
98
|
field_count = estimate_key_size(key, policy)
|
99
|
+
|
100
|
+
predexp_size = estimate_predexp(policy.predexp)
|
101
|
+
field_count += 1 if predexp_size > 0
|
96
102
|
|
97
103
|
bins.each do |bin|
|
98
104
|
estimate_operation_size_for_bin(bin)
|
@@ -102,6 +108,7 @@ module Aerospike
|
|
102
108
|
|
103
109
|
write_header_with_policy(policy, 0, INFO2_WRITE, field_count, bins.length)
|
104
110
|
write_key(key, policy)
|
111
|
+
write_predexp(policy.predexp, predexp_size)
|
105
112
|
|
106
113
|
bins.each do |bin|
|
107
114
|
write_operation_for_bin(bin, operation)
|
@@ -114,9 +121,14 @@ module Aerospike
|
|
114
121
|
def set_delete(policy, key)
|
115
122
|
begin_cmd
|
116
123
|
field_count = estimate_key_size(key)
|
124
|
+
|
125
|
+
predexp_size = estimate_predexp(policy.predexp)
|
126
|
+
field_count += 1 if predexp_size > 0
|
127
|
+
|
117
128
|
size_buffer
|
118
129
|
write_header_with_policy(policy, 0, INFO2_WRITE|INFO2_DELETE, field_count, 0)
|
119
130
|
write_key(key)
|
131
|
+
write_predexp(policy.predexp, predexp_size)
|
120
132
|
end_cmd
|
121
133
|
end
|
122
134
|
|
@@ -124,10 +136,15 @@ module Aerospike
|
|
124
136
|
def set_touch(policy, key)
|
125
137
|
begin_cmd
|
126
138
|
field_count = estimate_key_size(key)
|
139
|
+
|
140
|
+
predexp_size = estimate_predexp(policy.predexp)
|
141
|
+
field_count += 1 if predexp_size > 0
|
142
|
+
|
127
143
|
estimate_operation_size
|
128
144
|
size_buffer
|
129
145
|
write_header_with_policy(policy, 0, INFO2_WRITE, field_count, 1)
|
130
146
|
write_key(key)
|
147
|
+
write_predexp(policy.predexp, predexp_size)
|
131
148
|
write_operation_for_operation_type(Aerospike::Operation::TOUCH)
|
132
149
|
end_cmd
|
133
150
|
end
|
@@ -136,9 +153,14 @@ module Aerospike
|
|
136
153
|
def set_exists(policy, key)
|
137
154
|
begin_cmd
|
138
155
|
field_count = estimate_key_size(key)
|
156
|
+
|
157
|
+
predexp_size = estimate_predexp(policy.predexp)
|
158
|
+
field_count += 1 if predexp_size > 0
|
159
|
+
|
139
160
|
size_buffer
|
140
161
|
write_header(policy, INFO1_READ|INFO1_NOBINDATA, 0, field_count, 0)
|
141
162
|
write_key(key)
|
163
|
+
write_predexp(policy.predexp, predexp_size)
|
142
164
|
end_cmd
|
143
165
|
end
|
144
166
|
|
@@ -146,9 +168,14 @@ module Aerospike
|
|
146
168
|
def set_read_for_key_only(policy, key)
|
147
169
|
begin_cmd
|
148
170
|
field_count = estimate_key_size(key)
|
171
|
+
|
172
|
+
predexp_size = estimate_predexp(policy.predexp)
|
173
|
+
field_count += 1 if predexp_size > 0
|
174
|
+
|
149
175
|
size_buffer
|
150
176
|
write_header(policy, INFO1_READ|INFO1_GET_ALL, 0, field_count, 0)
|
151
177
|
write_key(key)
|
178
|
+
write_predexp(policy.predexp, predexp_size)
|
152
179
|
end_cmd
|
153
180
|
end
|
154
181
|
|
@@ -157,6 +184,10 @@ module Aerospike
|
|
157
184
|
if bin_names && bin_names.length > 0
|
158
185
|
begin_cmd
|
159
186
|
field_count = estimate_key_size(key)
|
187
|
+
|
188
|
+
predexp_size = estimate_predexp(policy.predexp)
|
189
|
+
field_count += 1 if predexp_size > 0
|
190
|
+
|
160
191
|
|
161
192
|
bin_names.each do |bin_name|
|
162
193
|
estimate_operation_size_for_bin_name(bin_name)
|
@@ -165,6 +196,7 @@ module Aerospike
|
|
165
196
|
size_buffer
|
166
197
|
write_header(policy, INFO1_READ, 0, field_count, bin_names.length)
|
167
198
|
write_key(key)
|
199
|
+
write_predexp(policy.predexp, predexp_size)
|
168
200
|
|
169
201
|
bin_names.each do |bin_name|
|
170
202
|
write_operation_for_bin_name(bin_name, Aerospike::Operation::READ)
|
@@ -180,6 +212,10 @@ module Aerospike
|
|
180
212
|
def set_read_header(policy, key)
|
181
213
|
begin_cmd
|
182
214
|
field_count = estimate_key_size(key)
|
215
|
+
|
216
|
+
predexp_size = estimate_predexp(policy.predexp)
|
217
|
+
field_count += 1 if predexp_size > 0
|
218
|
+
|
183
219
|
estimate_operation_size_for_bin_name('')
|
184
220
|
size_buffer
|
185
221
|
|
@@ -190,6 +226,7 @@ module Aerospike
|
|
190
226
|
write_header(policy, INFO1_READ, 0, field_count, 1)
|
191
227
|
|
192
228
|
write_key(key)
|
229
|
+
write_predexp(policy.predexp, predexp_size)
|
193
230
|
write_operation_for_bin_name('', Aerospike::Operation::READ)
|
194
231
|
end_cmd
|
195
232
|
end
|
@@ -198,6 +235,10 @@ module Aerospike
|
|
198
235
|
def set_operate(policy, key, operations)
|
199
236
|
begin_cmd
|
200
237
|
field_count = estimate_key_size(key, policy)
|
238
|
+
|
239
|
+
predexp_size = estimate_predexp(policy.predexp)
|
240
|
+
field_count += 1 if predexp_size > 0
|
241
|
+
|
201
242
|
read_attr = 0
|
202
243
|
write_attr = 0
|
203
244
|
read_header = false
|
@@ -205,19 +246,22 @@ module Aerospike
|
|
205
246
|
operations.each do |operation|
|
206
247
|
case operation.op_type
|
207
248
|
when Aerospike::Operation::READ
|
208
|
-
|
249
|
+
read_attr |= INFO1_READ
|
209
250
|
|
210
251
|
# Read all bins if no bin is specified.
|
211
252
|
read_attr |= INFO1_GET_ALL unless operation.bin_name
|
212
253
|
|
213
254
|
when Aerospike::Operation::READ_HEADER
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
255
|
+
# The server does not currently return record header data with _INFO1_NOBINDATA attribute set.
|
256
|
+
# The workaround is to request a non-existent bin.
|
257
|
+
# TODO: Fix this on server.
|
258
|
+
# read_attr |= _INFO1_READ | _INFO1_NOBINDATA
|
259
|
+
read_attr |= INFO1_READ
|
219
260
|
read_header = true
|
220
261
|
|
262
|
+
when Aerospike::Operation::CDT_READ
|
263
|
+
read_attr |= INFO1_READ
|
264
|
+
|
221
265
|
else
|
222
266
|
write_attr = INFO2_WRITE
|
223
267
|
end
|
@@ -232,6 +276,7 @@ module Aerospike
|
|
232
276
|
write_header(policy, read_attr, write_attr, field_count, operations.length)
|
233
277
|
end
|
234
278
|
write_key(key, policy)
|
279
|
+
write_predexp(policy.predexp, predexp_size)
|
235
280
|
|
236
281
|
operations.each do |operation|
|
237
282
|
write_operation_for_operation(operation)
|
@@ -245,6 +290,10 @@ module Aerospike
|
|
245
290
|
def set_udf(policy, key, package_name, function_name, args)
|
246
291
|
begin_cmd
|
247
292
|
field_count = estimate_key_size(key, policy)
|
293
|
+
|
294
|
+
predexp_size = estimate_predexp(policy.predexp)
|
295
|
+
field_count += 1 if predexp_size > 0
|
296
|
+
|
248
297
|
arg_bytes = args.to_bytes
|
249
298
|
|
250
299
|
field_count += estimate_udf_size(package_name, function_name, arg_bytes)
|
@@ -252,6 +301,7 @@ module Aerospike
|
|
252
301
|
|
253
302
|
write_header(policy, 0, INFO2_WRITE, field_count, 0)
|
254
303
|
write_key(key, policy)
|
304
|
+
write_predexp(policy.predexp, predexp_size)
|
255
305
|
write_field_string(package_name, Aerospike::FieldType::UDF_PACKAGE_NAME)
|
256
306
|
write_field_string(function_name, Aerospike::FieldType::UDF_FUNCTION)
|
257
307
|
write_field_bytes(arg_bytes, Aerospike::FieldType::UDF_ARGLIST)
|
@@ -273,6 +323,9 @@ module Aerospike
|
|
273
323
|
@data_offset += set_name.bytesize + FIELD_HEADER_SIZE
|
274
324
|
field_count += 1
|
275
325
|
end
|
326
|
+
|
327
|
+
predexp_size = estimate_predexp(policy.predexp)
|
328
|
+
field_count += 1 if predexp_size > 0
|
276
329
|
|
277
330
|
# Estimate scan options size.
|
278
331
|
@data_offset += 2 + FIELD_HEADER_SIZE
|
@@ -310,6 +363,8 @@ module Aerospike
|
|
310
363
|
write_field_string(set_name, Aerospike::FieldType::TABLE)
|
311
364
|
end
|
312
365
|
|
366
|
+
write_predexp(policy.predexp, predexp_size)
|
367
|
+
|
313
368
|
write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
314
369
|
|
315
370
|
priority = policy.priority & 0xFF
|
@@ -498,6 +553,16 @@ module Aerospike
|
|
498
553
|
@data_offset += OPERATION_HEADER_SIZE
|
499
554
|
end
|
500
555
|
|
556
|
+
def estimate_predexp(predexp)
|
557
|
+
if predexp && predexp.size > 0
|
558
|
+
@data_offset += FIELD_HEADER_SIZE
|
559
|
+
sz = Aerospike::PredExp.estimate_size(predexp)
|
560
|
+
@data_offset += sz
|
561
|
+
return sz
|
562
|
+
end
|
563
|
+
return 0
|
564
|
+
end
|
565
|
+
|
501
566
|
# Generic header write.
|
502
567
|
def write_header(policy, read_attr, write_attr, field_count, operation_count)
|
503
568
|
read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
|
@@ -696,6 +761,15 @@ module Aerospike
|
|
696
761
|
@data_offset += 1
|
697
762
|
end
|
698
763
|
|
764
|
+
def write_predexp(predexp, predexp_size)
|
765
|
+
if predexp && predexp.size > 0
|
766
|
+
write_field_header(predexp_size, Aerospike::FieldType::PREDEXP)
|
767
|
+
@data_offset = Aerospike::PredExp.write(
|
768
|
+
predexp, @data_buffer, @data_offset
|
769
|
+
)
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
699
773
|
def begin_cmd
|
700
774
|
@data_offset = MSG_TOTAL_HEADER_SIZE
|
701
775
|
end
|
@@ -43,13 +43,25 @@ module Aerospike
|
|
43
43
|
|
44
44
|
result_code = @data_buffer.read(13).ord & 0xFF
|
45
45
|
|
46
|
-
if
|
47
|
-
|
46
|
+
if result_code == 0
|
47
|
+
@existed = true
|
48
|
+
return
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
+
if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
52
|
+
@existed = false
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
if result_code == Aerospike::ResultCode::FILTERED_OUT
|
57
|
+
if @policy.fail_on_filtered_out
|
58
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
59
|
+
end
|
60
|
+
@existed = true
|
61
|
+
return
|
62
|
+
end
|
51
63
|
|
52
|
-
|
64
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
53
65
|
end
|
54
66
|
|
55
67
|
end # class
|
@@ -43,13 +43,25 @@ module Aerospike
|
|
43
43
|
|
44
44
|
result_code = @data_buffer.read(13).ord & 0xFF
|
45
45
|
|
46
|
-
if
|
47
|
-
|
46
|
+
if result_code == 0
|
47
|
+
@exists = true
|
48
|
+
return
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
+
if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
52
|
+
@exists = false
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
if result_code == Aerospike::ResultCode::FILTERED_OUT
|
57
|
+
if @policy.fail_on_filtered_out
|
58
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
59
|
+
end
|
60
|
+
@exists = true
|
61
|
+
return
|
62
|
+
end
|
51
63
|
|
52
|
-
|
64
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
53
65
|
end
|
54
66
|
|
55
67
|
end # class
|
@@ -59,10 +59,13 @@ module Aerospike
|
|
59
59
|
read_bytes(MSG_REMAINING_HEADER_SIZE)
|
60
60
|
result_code = @data_buffer.read(5).ord & 0xFF
|
61
61
|
|
62
|
-
# The only valid server return codes are "ok"
|
62
|
+
# The only valid server return codes are "ok", "not found" and "filtered out".
|
63
63
|
# If other return codes are received, then abort the batch.
|
64
|
-
if result_code != 0
|
65
|
-
|
64
|
+
if result_code != 0
|
65
|
+
if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR || result_code == Aerospike::ResultCode::FILTERED_OUT
|
66
|
+
else
|
67
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
68
|
+
end
|
66
69
|
end
|
67
70
|
|
68
71
|
# If cmd is the end marker of the response, do not proceed further
|
@@ -76,29 +76,36 @@ module Aerospike
|
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
-
if result_code
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
begin
|
84
|
-
@record = parse_record(op_count, field_count, generation, expiration)
|
85
|
-
handle_udf_error(result_code)
|
86
|
-
rescue => e
|
87
|
-
Aerospike.logger.error("UDF execution error: #{e}")
|
88
|
-
raise e
|
89
|
-
end
|
90
|
-
|
79
|
+
if result_code == 0
|
80
|
+
if op_count == 0
|
81
|
+
@record = Record.new(@node, @key, nil, generation, expiration)
|
82
|
+
return
|
91
83
|
end
|
92
|
-
|
93
|
-
|
84
|
+
|
85
|
+
@record = parse_record(op_count, field_count, generation, expiration)
|
86
|
+
return
|
94
87
|
end
|
95
88
|
|
96
|
-
if
|
97
|
-
|
89
|
+
return nil if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
90
|
+
|
91
|
+
if result_code == Aerospike::ResultCode::FILTERED_OUT
|
92
|
+
if @policy.fail_on_filtered_out
|
93
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
94
|
+
end
|
98
95
|
return
|
99
96
|
end
|
100
97
|
|
101
|
-
|
98
|
+
if result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE
|
99
|
+
begin
|
100
|
+
@record = parse_record(op_count, field_count, generation, expiration)
|
101
|
+
handle_udf_error(result_code)
|
102
|
+
rescue => e
|
103
|
+
Aerospike.logger.error("UDF execution error: #{e}")
|
104
|
+
raise e
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
102
109
|
end
|
103
110
|
|
104
111
|
def handle_udf_error(result_code)
|
@@ -47,15 +47,23 @@ module Aerospike
|
|
47
47
|
generation = @data_buffer.read_int32(14)
|
48
48
|
expiration = @data_buffer.read_int32(18)
|
49
49
|
@record = Record.new(@node, @key, nil, generation, expiration)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
return
|
51
|
+
end
|
52
|
+
|
53
|
+
if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
54
|
+
@record = nil
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
if result_code == Aerospike::ResultCode::FILTERED_OUT
|
59
|
+
@record = nil
|
60
|
+
if @policy.fail_on_filtered_out
|
54
61
|
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
55
62
|
end
|
63
|
+
return
|
56
64
|
end
|
57
65
|
|
58
|
-
|
66
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
59
67
|
end
|
60
68
|
|
61
69
|
end # class
|
@@ -40,9 +40,16 @@ module Aerospike
|
|
40
40
|
|
41
41
|
result_code = @data_buffer.read(13).ord & 0xFF
|
42
42
|
|
43
|
-
|
43
|
+
return if result_code == 0
|
44
44
|
|
45
|
-
|
45
|
+
if result_code == Aerospike::ResultCode::FILTERED_OUT
|
46
|
+
if @policy.fail_on_filtered_out
|
47
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
48
|
+
end
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
46
53
|
end
|
47
54
|
|
48
55
|
end # class
|
@@ -52,11 +52,16 @@ module Aerospike
|
|
52
52
|
|
53
53
|
result_code = @data_buffer.read(13).ord & 0xFF
|
54
54
|
|
55
|
-
if result_code
|
56
|
-
|
55
|
+
return if result_code == 0
|
56
|
+
|
57
|
+
if result_code == Aerospike::ResultCode::FILTERED_OUT
|
58
|
+
if @policy.fail_on_filtered_out
|
59
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
60
|
+
end
|
61
|
+
return
|
57
62
|
end
|
58
63
|
|
59
|
-
|
64
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
60
65
|
end
|
61
66
|
|
62
67
|
end # class
|
data/lib/aerospike/operation.rb
CHANGED
@@ -31,6 +31,7 @@ module Aerospike
|
|
31
31
|
APPEND = 9
|
32
32
|
PREPEND = 10
|
33
33
|
TOUCH = 11
|
34
|
+
DELETE = 14
|
34
35
|
|
35
36
|
def initialize(op_type, bin_name=nil, bin_value=NullValue.new)
|
36
37
|
@op_type = op_type
|
@@ -71,6 +72,10 @@ module Aerospike
|
|
71
72
|
Operation.new(TOUCH)
|
72
73
|
end
|
73
74
|
|
75
|
+
def self.delete
|
76
|
+
Operation.new(DELETE)
|
77
|
+
end
|
78
|
+
|
74
79
|
end
|
75
80
|
|
76
81
|
end # module
|
@@ -22,7 +22,8 @@ module Aerospike
|
|
22
22
|
# Container object for client policy command.
|
23
23
|
class Policy
|
24
24
|
|
25
|
-
attr_accessor :priority, :timeout, :max_retries, :sleep_between_retries, :consistency_level
|
25
|
+
attr_accessor :priority, :timeout, :max_retries, :sleep_between_retries, :consistency_level,
|
26
|
+
:predexp, :fail_on_filtered_out
|
26
27
|
|
27
28
|
def initialize(opt={})
|
28
29
|
# Container object for transaction policy attributes used in all database
|
@@ -32,6 +33,50 @@ module Aerospike
|
|
32
33
|
# Currently, only used for scans.
|
33
34
|
@priority = opt[:priority] || Priority::DEFAULT
|
34
35
|
|
36
|
+
# Set optional predicate expression filters in postfix notation.
|
37
|
+
# Predicate expression filters are applied on the query results on the server.
|
38
|
+
# Predicate expression filters may occur on any bin in the record.
|
39
|
+
# Requires Aerospike Server versions >= 3.12
|
40
|
+
#
|
41
|
+
# Postfix notation is described here: http://wiki.c2.com/?PostfixNotation
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
#
|
45
|
+
# (c >= 11 and c <= 20) or (d > 3 and (d < 5)
|
46
|
+
# policy.predexp = [
|
47
|
+
# PredExp.integer_bin("c"),
|
48
|
+
# PredExp.integer_value(11),
|
49
|
+
# PredExp.integer_greater_eq(),
|
50
|
+
# PredExp.integer_bin("c"),
|
51
|
+
# PredExp.integer_value(20),
|
52
|
+
# PredExp.integer_less_eq(),
|
53
|
+
# PredExp.and(2),
|
54
|
+
# PredExp.integer_bin("d"),
|
55
|
+
# PredExp.integer_value(3),
|
56
|
+
# PredExp.integer_greater(),
|
57
|
+
# PredExp.integer_bin("d"),
|
58
|
+
# PredExp.integer_value(5),
|
59
|
+
# PredExp.integer_less(),
|
60
|
+
# PredExp.and(2),
|
61
|
+
# PredExp.or(2)
|
62
|
+
# ]
|
63
|
+
#
|
64
|
+
# # Record last update time > 2017-01-15
|
65
|
+
# policy.predexp = [
|
66
|
+
# PredExp.rec_last_update(),
|
67
|
+
# PredExp.integer_value(Time.new(2017, 1, 15).to_i),
|
68
|
+
# PredExp.integer_greater(),
|
69
|
+
# PredExp.integer_greater()
|
70
|
+
# ]
|
71
|
+
@predexp = opt[:predexp] || nil
|
72
|
+
|
73
|
+
|
74
|
+
# Throw exception if @predexp is defined and that filter evaluates
|
75
|
+
# to false (transaction ignored). The Aerospike::Exceptions::Aerospike
|
76
|
+
# will contain result code Aerospike::ResultCode::FILTERED_OUT.
|
77
|
+
# This field is not applicable to batch, scan or query commands.
|
78
|
+
@fail_on_filtered_out = opt[:fail_on_filtered_out] || false
|
79
|
+
|
35
80
|
# How replicas should be consulted in a read operation to provide the desired
|
36
81
|
# consistency guarantee. Default to allowing one replica to be used in the
|
37
82
|
# read operation.
|
@@ -93,9 +93,11 @@ module Aerospike
|
|
93
93
|
@data_offset += 8 + FIELD_HEADER_SIZE
|
94
94
|
fieldCount+=1
|
95
95
|
|
96
|
-
|
96
|
+
predexp = @policy.predexp || @statement.predexp
|
97
|
+
|
98
|
+
if predexp
|
97
99
|
@data_offset += FIELD_HEADER_SIZE
|
98
|
-
predSize = Aerospike::PredExp.estimate_size(
|
100
|
+
predSize = Aerospike::PredExp.estimate_size(predexp)
|
99
101
|
@data_offset += predSize
|
100
102
|
fieldCount += 1
|
101
103
|
end
|
@@ -184,10 +186,10 @@ module Aerospike
|
|
184
186
|
@data_buffer.write_int64(@statement.task_id, @data_offset)
|
185
187
|
@data_offset += 8
|
186
188
|
|
187
|
-
if
|
189
|
+
if predexp
|
188
190
|
write_field_header(predSize, Aerospike::FieldType::PREDEXP)
|
189
191
|
@data_offset = Aerospike::PredExp.write(
|
190
|
-
|
192
|
+
predexp, @data_buffer, @data_offset
|
191
193
|
)
|
192
194
|
end
|
193
195
|
|
@@ -43,7 +43,14 @@ module Aerospike
|
|
43
43
|
# aggregation function.
|
44
44
|
@filters = []
|
45
45
|
|
46
|
-
# Predicate expressions
|
46
|
+
# Predicate expressions in postfix notation. If the expression is evaluated to false,
|
47
|
+
# the record will be ommited in the results.
|
48
|
+
#
|
49
|
+
# This method is redundant because PredExp can now be set in the base Policy for
|
50
|
+
# any transaction (including queries).
|
51
|
+
#
|
52
|
+
# NOTE : Policy.predexp takes precedence to this value. This value will be
|
53
|
+
# deprecated in the future.
|
47
54
|
@predexp = nil
|
48
55
|
|
49
56
|
@package_name = nil
|
@@ -116,6 +116,12 @@ module Aerospike
|
|
116
116
|
# Enterprise-only feature not supported by the community edition
|
117
117
|
ENTERPRISE_ONLY = 25
|
118
118
|
|
119
|
+
# The operation cannot be applied to the current bin value on the server.
|
120
|
+
OP_NOT_APPLICABLE = 26
|
121
|
+
|
122
|
+
# The transaction was not performed because the predexp was false.
|
123
|
+
FILTERED_OUT = 27
|
124
|
+
|
119
125
|
# There are no more records left for query.
|
120
126
|
QUERY_END = 50
|
121
127
|
|
@@ -167,9 +173,6 @@ module Aerospike
|
|
167
173
|
# A user defined function returned an error code.
|
168
174
|
UDF_BAD_RESPONSE = 100
|
169
175
|
|
170
|
-
# The requested item in a large collection was not found.
|
171
|
-
LARGE_ITEM_NOT_FOUND = 125
|
172
|
-
|
173
176
|
# Secondary index already exists.
|
174
177
|
INDEX_FOUND = 200
|
175
178
|
|
@@ -295,6 +298,12 @@ module Aerospike
|
|
295
298
|
when ENTERPRISE_ONLY
|
296
299
|
"Enterprise-only feature not supported by community edition"
|
297
300
|
|
301
|
+
when OP_NOT_APPLICABLE
|
302
|
+
"The operation cannot be applied to the current bin value on the server."
|
303
|
+
|
304
|
+
when FILTERED_OUT
|
305
|
+
"The transaction was not performed because the predexp was false."
|
306
|
+
|
298
307
|
when QUERY_END
|
299
308
|
"Query end"
|
300
309
|
|
@@ -352,9 +361,6 @@ module Aerospike
|
|
352
361
|
when UDF_BAD_RESPONSE
|
353
362
|
"UDF d error"
|
354
363
|
|
355
|
-
when LARGE_ITEM_NOT_FOUND
|
356
|
-
"Large collection item not found"
|
357
|
-
|
358
364
|
when INDEX_FOUND
|
359
365
|
"Index already exists"
|
360
366
|
|
@@ -22,14 +22,11 @@ require 'aerospike/aerospike_exception'
|
|
22
22
|
module Aerospike
|
23
23
|
# Polymorphic value classes used to efficiently serialize objects into the wire protocol.
|
24
24
|
class Value #:nodoc:
|
25
|
-
INTEGER_RANGE = Range.new(-2**63, 2**63 - 1).freeze
|
26
25
|
|
27
26
|
def self.of(value)
|
28
27
|
case value
|
29
|
-
when nil
|
30
|
-
res = NULL
|
31
28
|
when Integer
|
32
|
-
if
|
29
|
+
if value.bit_length < 64
|
33
30
|
res = IntegerValue.new(value)
|
34
31
|
else
|
35
32
|
# big nums > 2**63 are not supported
|
@@ -49,6 +46,8 @@ module Aerospike
|
|
49
46
|
res = ListValue.new(value)
|
50
47
|
when GeoJSON
|
51
48
|
res = GeoJSONValue.new(value)
|
49
|
+
when nil
|
50
|
+
res = NULL
|
52
51
|
else
|
53
52
|
# throw an exception for anything that is not supported.
|
54
53
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::TYPE_NOT_SUPPORTED, "Value type #{value.class} not supported.")
|
@@ -57,6 +56,22 @@ module Aerospike
|
|
57
56
|
res
|
58
57
|
end
|
59
58
|
|
59
|
+
def self.validate_hash_key(value)
|
60
|
+
case value
|
61
|
+
when Integer
|
62
|
+
if value.bit_length >= 64
|
63
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::TYPE_NOT_SUPPORTED, "Value type #{value.class} not supported as hash key.")
|
64
|
+
end
|
65
|
+
when Float
|
66
|
+
when String
|
67
|
+
when Symbol
|
68
|
+
when nil
|
69
|
+
else
|
70
|
+
# throw an exception for anything that is not supported.
|
71
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::TYPE_NOT_SUPPORTED, "Value type #{value.class} not supported as hash key.")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
60
75
|
end # Value
|
61
76
|
|
62
77
|
# Empty value.
|
@@ -137,7 +152,7 @@ module Aerospike
|
|
137
152
|
end
|
138
153
|
end
|
139
154
|
|
140
|
-
INFINITY = InfinityValue.new.freeze
|
155
|
+
INFINITY = Value::INFINITY = InfinityValue.new.freeze
|
141
156
|
|
142
157
|
# Wildcard value.
|
143
158
|
class WildcardValue < Value #:nodoc:
|
@@ -178,7 +193,7 @@ module Aerospike
|
|
178
193
|
end
|
179
194
|
end
|
180
195
|
|
181
|
-
WILDCARD = WildcardValue.new.freeze
|
196
|
+
WILDCARD = Value::WILDCARD = WildcardValue.new.freeze
|
182
197
|
|
183
198
|
# Byte array value.
|
184
199
|
class BytesValue < Value #:nodoc:
|
@@ -356,21 +371,16 @@ module Aerospike
|
|
356
371
|
class ListValue < Value #:nodoc:
|
357
372
|
|
358
373
|
def initialize(list)
|
359
|
-
@list = list ||
|
360
|
-
Packer.use do |packer|
|
361
|
-
pack(packer)
|
362
|
-
@bytes = packer.bytes
|
363
|
-
end
|
364
|
-
self
|
374
|
+
@list = list || []
|
365
375
|
end
|
366
376
|
|
367
377
|
def estimate_size
|
368
|
-
|
378
|
+
bytes.bytesize
|
369
379
|
end
|
370
380
|
|
371
381
|
def write(buffer, offset)
|
372
|
-
buffer.write_binary(
|
373
|
-
|
382
|
+
buffer.write_binary(bytes, offset)
|
383
|
+
bytes.bytesize
|
374
384
|
end
|
375
385
|
|
376
386
|
def pack(packer)
|
@@ -389,13 +399,26 @@ module Aerospike
|
|
389
399
|
end
|
390
400
|
|
391
401
|
def to_bytes
|
392
|
-
|
402
|
+
bytes
|
393
403
|
end
|
394
404
|
|
395
405
|
def to_s
|
396
406
|
@list.map{|v| v.to_s}.to_s
|
397
407
|
end
|
398
408
|
|
409
|
+
private
|
410
|
+
|
411
|
+
def bytes
|
412
|
+
return @bytes if @bytes
|
413
|
+
|
414
|
+
Packer.use do |packer|
|
415
|
+
pack(packer)
|
416
|
+
@bytes = packer.bytes
|
417
|
+
end
|
418
|
+
|
419
|
+
@bytes
|
420
|
+
end
|
421
|
+
|
399
422
|
end
|
400
423
|
|
401
424
|
# #######################################/
|
@@ -406,28 +429,22 @@ module Aerospike
|
|
406
429
|
|
407
430
|
def initialize(vmap)
|
408
431
|
@vmap = vmap || {}
|
409
|
-
|
410
|
-
Packer.use do |packer|
|
411
|
-
pack(packer)
|
412
|
-
@bytes = packer.bytes
|
413
|
-
end
|
414
|
-
|
415
|
-
self
|
416
432
|
end
|
417
433
|
|
418
434
|
def estimate_size
|
419
|
-
|
435
|
+
bytes.bytesize
|
420
436
|
end
|
421
437
|
|
422
438
|
def write(buffer, offset)
|
423
|
-
buffer.write_binary(
|
424
|
-
|
439
|
+
buffer.write_binary(bytes, offset)
|
440
|
+
bytes.bytesize
|
425
441
|
end
|
426
442
|
|
427
443
|
def pack(packer)
|
428
444
|
packer.write_map_header(@vmap.length)
|
429
|
-
# @vmap.each do |key, val|
|
430
445
|
for key, val in @vmap
|
446
|
+
Value.validate_hash_key(key)
|
447
|
+
|
431
448
|
Value.of(key).pack(packer)
|
432
449
|
Value.of(val).pack(packer)
|
433
450
|
end
|
@@ -442,13 +459,26 @@ module Aerospike
|
|
442
459
|
end
|
443
460
|
|
444
461
|
def to_bytes
|
445
|
-
|
462
|
+
bytes
|
446
463
|
end
|
447
464
|
|
448
465
|
def to_s
|
449
466
|
@vmap.map{|k, v| "#{k.to_s} => #{v.to_s}" }.to_s
|
450
467
|
end
|
451
468
|
|
469
|
+
private
|
470
|
+
|
471
|
+
def bytes
|
472
|
+
return @bytes if @bytes
|
473
|
+
|
474
|
+
Packer.use do |packer|
|
475
|
+
pack(packer)
|
476
|
+
@bytes = packer.bytes
|
477
|
+
end
|
478
|
+
|
479
|
+
@bytes
|
480
|
+
end
|
481
|
+
|
452
482
|
end
|
453
483
|
|
454
484
|
# #######################################/
|
data/lib/aerospike/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aerospike
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khosrow Afroozeh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-04-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|
@@ -196,8 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
196
|
- !ruby/object:Gem::Version
|
197
197
|
version: '0'
|
198
198
|
requirements: []
|
199
|
-
|
200
|
-
rubygems_version: 2.7.9
|
199
|
+
rubygems_version: 3.1.2
|
201
200
|
signing_key:
|
202
201
|
specification_version: 4
|
203
202
|
summary: An Aerospike driver for Ruby.
|