aerospike 2.11.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|