aerospike 2.7.0 → 2.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2351767e50e34f9aec1da0eb58c6d5fb5b8a39f83d3aa2d2f9c88ed5d446b15a
4
- data.tar.gz: 7104f9494a571dcf34a4809f0e4331acc76981649a53df06dd5f5c3ceddbcd0d
3
+ metadata.gz: 604462bd062c1fea97323684cfe3512a962e52c69b651e6ee86251a22769fcf0
4
+ data.tar.gz: 6d62d86f30470b07daaa46cfef8188addd558d60be17c0e5398e6fef772ef37f
5
5
  SHA512:
6
- metadata.gz: a48674b7bf187a0660d0a2b0e9c070f1b9f270d31dda522a2264cb2821470c193d2714944f35e4c65c2f05ee06fc299894d4721e348b8c986d5124f8d95ae2ef
7
- data.tar.gz: febaffccf38b34e5b6653ce078630eacf73fead0d2cd840d09a87016a3adc3a8ff26a00460031a18d52d8a3bda6e9def1c7259917291f79857e020212812ebb1
6
+ metadata.gz: 631961c7e7d06bdaeeb8aeb456fe02c52b000f28ae4f0293ace79842dc9d1ccf83c478b06826b11d939b60663cc844183e32b1d5b3b41b925035e007d9fdec5f
7
+ data.tar.gz: c5f5e285521e445d35c2723a1849d2072dcbd72223998b3f5559d0bc7eac563917be43d8c1ec9dbc81e04a65fd537502bede46df7808e10bd8d63f3a5ce93d78
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
- v2.7.0 / 2018-04-12
2
- ===================
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [2.8.0] - 2018-08-06
8
+
9
+ * **New Features**
10
+ * Support latest CDT List/Map server-side operations: [[#69](https://github.com/aerospike/aerospike-client-ruby/pull/69)]
11
+ * Operations on Ordered Lists & Bounded Lists via new List Policy. (Requires server version v3.16.0 or later.)
12
+ * Option to invert selection criteria for certain List/Map get/remove operations. (Requires server version v3.16.0 or later.)
13
+ * List/Map index/rank relative get/remove operations. (Requires server version v4.3.0 or later.)
14
+ * Partial list/map updates using PARTIAL / NO_FAIL write flags. (Requires server version v4.3.0 or later.)
15
+ * Benchmarks: Output total TPS metrics at end of run [[#71](https://github.com/aerospike/aerospike-client-ruby/pull/71)]
16
+
17
+ * **Bug Fixes**
18
+ * Check connection status of sockets retrieved from connection pool [[#72](https://github.com/aerospike/aerospike-client-ruby/pull/72)]
19
+
20
+ * **Updates**
21
+ * Add JRuby back to CI test matrix [[#70](https://github.com/aerospike/aerospike-client-ruby/pull/70)]
22
+
23
+ ## [2.7.0] - 2018-04-12
3
24
 
4
25
  * **New Features**
5
26
  * Batch Index protocol support. Thanks to [@deenbandhu-agarwal](https://github.com/deenbandhu-agarwal)! [[#61](https://github.com/aerospike/aerospike-client-ruby/pull/61)]
@@ -7,8 +28,7 @@ v2.7.0 / 2018-04-12
7
28
  * New node removal strategy. Thanks to [@wallin](https://github.com/wallin)! [[#63](https://github.com/aerospike/aerospike-client-ruby/pull/63)]
8
29
  * Support for IPv6. Requires Aerospike Enterprise Edition v3.10 or later. Thanks to [@wallin](https://github.com/wallin)! [[#65](https://github.com/aerospike/aerospike-client-ruby/pull/65)]
9
30
 
10
- v2.6.0 / 2018-03-27
11
- ===================
31
+ ## [2.6.0] - 2018-03-27
12
32
 
13
33
  * **New Features**
14
34
  * Support for peers protocol for cluster discovery. Requires Aerospike server version 3.10 or later. Thanks to [@wallin](https://github.com/wallin) of [castle.io](https://castle.io/)! [[#59](https://github.com/aerospike/aerospike-client-ruby/pull/59)]
@@ -20,8 +40,7 @@ v2.6.0 / 2018-03-27
20
40
  * **Updates**
21
41
  * Update minimum required Ruby version to v2.3.
22
42
 
23
- v2.5.1 / 2018-01-25
24
- ===================
43
+ ## [2.5.1] - 2018-01-25
25
44
 
26
45
  * **Bug Fixes**
27
46
  * Some secondary index queries fail with parameter error on Aerospike Server v3.15.1.x [#57](https://github.com/aerospike/aerospike-client-ruby/issues/57)
@@ -30,8 +49,7 @@ v2.5.1 / 2018-01-25
30
49
  * Added Ruby 2.5 to test matrix
31
50
  * Updated documentation for Client#truncate command [CLIENT-985]
32
51
 
33
- v2.5.0 / 2017-10-10
34
- ===================
52
+ ## [2.5.0] - 2017-10-10
35
53
 
36
54
  * **New Features**
37
55
  * Support nobins flag on query operations
@@ -41,8 +59,7 @@ v2.5.0 / 2017-10-10
41
59
  * The deprecated Large Data Types(LDT) feature has been removed.
42
60
  * Ruby 2.1 has been removed from the client's test matrix as [official support for Ruby 2.1 has ended in Apr 2017](https://www.ruby-lang.org/en/news/2017/04/01/support-of-ruby-2-1-has-ended/). Nothing has changed in the client that would break compatibility with Ruby 2.1 yet. But compatibility is not guaranteed for future client releases.
43
61
 
44
- v2.4.0 / 2017-04-06
45
- ===================
62
+ ## [2.4.0] - 2017-04-06
46
63
 
47
64
  * **New Features**
48
65
  * Support ns/set truncate command [#47](https://github.com/aerospike/aerospike-client-ruby/issues/47)
@@ -54,8 +71,7 @@ v2.4.0 / 2017-04-06
54
71
  * **Updates**
55
72
  * Ruby 2.0 has been removed from the client's test matrix as [official support for Ruby 2.0 has ended in Feb 2016](https://www.ruby-lang.org/en/news/2016/02/24/support-plan-of-ruby-2-0-0-and-2-1/). Nothing has changed in the client that would break compatibility with Ruby 2.0 yet. But compatibility is not guaranteed for future client releases. [#52](https://github.com/aerospike/aerospike-client-ruby/pull/52)
56
73
 
57
- v2.3.0 / 2017-01-04
58
- ===================
74
+ ## [2.3.0] - 2017-01-04
59
75
 
60
76
  * **Bug Fixes**
61
77
  * Fix BytesValue used as record key. [#42](https://github.com/aerospike/aerospike-client-ruby/issues/42)
@@ -63,8 +79,7 @@ v2.3.0 / 2017-01-04
63
79
  * **Changes**
64
80
  * Deprecate unsupport key types - only integer, string and byte keys are supported. [#43](https://github.com/aerospike/aerospike-client-ruby/issues/43)
65
81
 
66
- v2.2.1 / 2016-11-14
67
- ===================
82
+ ## [2.2.1] - 2016-11-14
68
83
 
69
84
  * **New Features**
70
85
  * Added constants `Aerospike::TTL::*` for "special" TTL values, incl. Aerospike::TTL::DONT_UPDATE (requires Aerospike Server v3.10.1 or later)
@@ -72,8 +87,7 @@ v2.2.1 / 2016-11-14
72
87
  * **Bug Fixes**
73
88
  * Fix "Add node failed: wrong number of arguments". [#41](https://github.com/aerospike/aerospike-client-ruby/issues/41)
74
89
 
75
- v2.2.0 / 2016-09-20
76
- ===================
90
+ ## [2.2.0] - 2016-09-20
77
91
 
78
92
  * **New Features**
79
93
  * Support for durable delete write policy [CLIENT-768]; requires Aerospike
@@ -92,8 +106,7 @@ v2.2.0 / 2016-09-20
92
106
  * Added note about potential issues with usage in Ruby on Rails with Phusion Passenger.
93
107
  * Amend/clean up documentation of client policies.
94
108
 
95
- v2.1.1 / 2016-08-16
96
- ===================
109
+ ## [2.1.1] - 2016-08-16
97
110
 
98
111
  * **Bug Fixes**
99
112
  * Fix incorrect expiration times on records fetched via batch_get or query operations. [#38](https://github.com/aerospike/aerospike-client-ruby/issues/38)
@@ -102,8 +115,7 @@ v2.1.1 / 2016-08-16
102
115
  * Add support for two new server error codes (23 & 24) introduced in Aerospike Server v3.9.1.
103
116
  * Records returned by batch_get operation should include the full key incl. the user key part.
104
117
 
105
- v2.1.0 / 2016-07-19
106
- ===================
118
+ ## [2.1.0] - 2016-07-19
107
119
 
108
120
  * **Fixes**
109
121
  * Fix a typo in the `max_retries` policy parameter name. [PR #37](https://github.com/aerospike/aerospike-client-ruby/pull/37) Thanks to [@murphyslaw](https://github.com/murphyslaw)!
@@ -114,8 +126,7 @@ v2.1.0 / 2016-07-19
114
126
  * Support for creating indexes on Lists and Maps [CLIENT-685]
115
127
  * Support GeoJSON values in Lists and Maps
116
128
 
117
- v2.0.0 / 2016-05-27
118
- ===================
129
+ ## [2.0.0] - 2016-05-27
119
130
 
120
131
  * **Breaking Changes** - Please refer to detailed list of [API changes](docs/api-changes.md#v2.0.0) for further details.
121
132
  * Incompatible integer key digests: digests for integer keys computed by v2 and v1 are different; the Aerospike server uses the key digest to retrieve records. This will impact your ability to read records with integer keys that were created by a v1 client version.
@@ -132,8 +143,7 @@ v2.0.0 / 2016-05-27
132
143
  * Fix digest creation for integer keys. [PR #34](https://github.com/aerospike/aerospike-client-ruby/pull/34). Thanks to [@murphyslaw](https://github.com/murphyslaw)!
133
144
  * Prevent "value must be enumerable" error when client cannot connect to cluster. [#35](https://github.com/aerospike/aerospike-client-ruby/issues/35). Thanks to [@rohanthewiz](https://github.com/rohanthewiz)!
134
145
 
135
- 1.0.12 / 2016-02-11
136
- ===================
146
+ ## [1.0.12] - 2016-02-11
137
147
 
138
148
  * **Fixes**:
139
149
 
@@ -144,8 +154,7 @@ v2.0.0 / 2016-05-27
144
154
  bins; thanks to [fs-wu](https://github.com/fs-wu) for finding the issue and
145
155
  reporting it. [aerospike/aerospike-client-ruby#33]
146
156
 
147
- 1.0.11 / 2015-12-04
148
- ===================
157
+ ## [1.0.11] - 2015-12-04
149
158
 
150
159
  Major feature and bug fix release.
151
160
 
@@ -174,8 +183,7 @@ v2.0.0 / 2016-05-27
174
183
 
175
184
  * Scan and Query termination has been fixed.
176
185
 
177
- 1.0.10 / 2015-09-22
178
- ===================
186
+ ## [1.0.10] - 2015-09-22
179
187
 
180
188
  Major fix release.
181
189
 
@@ -187,8 +195,7 @@ v2.0.0 / 2016-05-27
187
195
 
188
196
  * Fixes an issue with dead connections that would cause an infinite loop.
189
197
 
190
- 1.0.9 / 2015-08-11
191
- ==================
198
+ ## [1.0.9] - 2015-08-11
192
199
 
193
200
  Minor fix release.
194
201
 
@@ -196,8 +203,7 @@ v2.0.0 / 2016-05-27
196
203
 
197
204
  * Sends the original key value to the server for all relevant commands, including `operate` and `execute_udf`
198
205
 
199
- 1.0.8 / 2015-07-23
200
- ==================
206
+ ## [1.0.8] - 2015-07-23
201
207
 
202
208
  Minor fix release.
203
209
 
@@ -213,8 +219,7 @@ v2.0.0 / 2016-05-27
213
219
 
214
220
  * Fixes an issue with including the `statement.rb` in the manifest. Thanks to [Ángel M](https://github.com/Angelmmiguel)
215
221
 
216
- 1.0.7 / 2015-05-15
217
- ==================
222
+ ## [1.0.7] - 2015-05-15
218
223
 
219
224
  Minor fixes.
220
225
 
@@ -234,8 +239,7 @@ v2.0.0 / 2016-05-27
234
239
 
235
240
  * Removed deprecated `SetCapacity()` and `GetCapacity()` methods for LDTs.
236
241
 
237
- 1.0.6 / 2015-04-02
238
- ==================
242
+ ## [1.0.6] - 2015-04-02
239
243
 
240
244
  Minor fixes.
241
245
 
@@ -243,8 +247,7 @@ v2.0.0 / 2016-05-27
243
247
 
244
248
  * Fixed running a stream query without parameters to the function.
245
249
 
246
- 1.0.5 / 2015-03-25
247
- ==================
250
+ ## [1.0.5] - 2015-03-25
248
251
 
249
252
  Minor improvements.
250
253
 
@@ -252,8 +255,7 @@ v2.0.0 / 2016-05-27
252
255
 
253
256
  * Added `:execute_udf_on_query` method to `Aerospike::Client`
254
257
 
255
- 1.0.4 / 2015-03-24
256
- ==================
258
+ ## [1.0.4] - 2015-03-24
257
259
 
258
260
  Hot fix.
259
261
 
@@ -261,8 +263,7 @@ v2.0.0 / 2016-05-27
261
263
 
262
264
  * Close a socket if connection raises an exception to avoid leaking the file descriptor.
263
265
 
264
- 1.0.3 / 2015-03-24
265
- ==================
266
+ ## [1.0.3] - 2015-03-24
266
267
 
267
268
  Minor fixes and improvements.
268
269
 
@@ -275,8 +276,7 @@ v2.0.0 / 2016-05-27
275
276
  * Wait for a good connection on `socket.connect_nonblock` to prevent infinite loops on read/write operations.
276
277
 
277
278
 
278
- 1.0.2 / 2015-03-14
279
- ==================
279
+ ## [1.0.2] - 2015-03-14
280
280
 
281
281
  Minor improvements.
282
282
 
@@ -284,8 +284,7 @@ v2.0.0 / 2016-05-27
284
284
 
285
285
  * Added `:new_many` method to `Aerospike::Client`
286
286
 
287
- 1.0.1 / 2015-01-28
288
- ==================
287
+ ## [1.0.1] - 2015-01-28
289
288
 
290
289
  Hot fix.
291
290
 
@@ -293,8 +292,7 @@ v2.0.0 / 2016-05-27
293
292
 
294
293
  * Added `bcrypt` to the gem dependencies.
295
294
 
296
- 1.0.0 / 2015-01-26
297
- ==================
295
+ ## [1.0.0] - 2015-01-26
298
296
 
299
297
  Major release. With this release, Ruby client graduates to version 1.
300
298
 
@@ -316,8 +314,7 @@ v2.0.0 / 2016-05-27
316
314
 
317
315
  * fixed size returned from `BytesValue.write`
318
316
 
319
- 0.1.6 / 2014-12-28
320
- ==================
317
+ ## [0.1.6] - 2014-12-28
321
318
 
322
319
  Minor features added, minor fixes and improvements.
323
320
 
@@ -331,8 +328,7 @@ v2.0.0 / 2016-05-27
331
328
  * Fixed setting timeout on connection
332
329
  * Fixed exception handling typo for Connection#write
333
330
 
334
- 0.1.5 / 2014-12-08
335
- ==================
331
+ ## [0.1.5] - 2014-12-08
336
332
 
337
333
  Major features added, minor fixes and improvements.
338
334
 
@@ -345,8 +341,7 @@ v2.0.0 / 2016-05-27
345
341
 
346
342
  * Fixed getting back results only for specified bin names.
347
343
 
348
- 0.1.3 / 2014-10-27
349
- ==================
344
+ ## [0.1.3] - 2014-10-27
350
345
 
351
346
  Minor fix.
352
347
 
@@ -354,8 +349,7 @@ v2.0.0 / 2016-05-27
354
349
 
355
350
  * Fixed LDT bin and module name packing.
356
351
 
357
- 0.1.2 / 2014-10-25
358
- ==================
352
+ ## [0.1.2] - 2014-10-25
359
353
 
360
354
  Minor fix.
361
355
 
@@ -363,8 +357,7 @@ v2.0.0 / 2016-05-27
363
357
 
364
358
  * Fixed String unpacking for single byte strings.
365
359
 
366
- 0.1.1 / 2014-10-25
367
- ==================
360
+ ## [0.1.1] - 2014-10-25
368
361
 
369
362
  Minor fixes.
370
363
 
@@ -373,7 +366,6 @@ v2.0.0 / 2016-05-27
373
366
  * Fixed String packing header in Hash and Array.
374
367
  * #find on LDTs returns `nil` instad of raising an exception if the item is not found.
375
368
 
376
- 0.1.0 / 2014-10-14
377
- ==================
369
+ ## [0.1.0] - 2014-10-14
378
370
 
379
371
  * Initial Release.
data/lib/aerospike.rb CHANGED
@@ -27,6 +27,7 @@ require 'aerospike/atomic/atomic'
27
27
 
28
28
  require 'aerospike/client'
29
29
  require 'aerospike/utils/pool'
30
+ require 'aerospike/utils/connection_pool'
30
31
  require 'aerospike/utils/packer'
31
32
  require 'aerospike/utils/unpacker'
32
33
  require 'aerospike/utils/buffer'
@@ -63,9 +64,15 @@ require 'aerospike/command/unsupported_particle_type_validator'
63
64
  require 'aerospike/key'
64
65
  require 'aerospike/operation'
65
66
  require 'aerospike/cdt/list_operation'
67
+ require 'aerospike/cdt/list_order'
68
+ require 'aerospike/cdt/list_return_type'
69
+ require 'aerospike/cdt/list_sort_flags'
70
+ require 'aerospike/cdt/list_write_flags'
71
+ require 'aerospike/cdt/list_policy'
66
72
  require 'aerospike/cdt/map_operation'
67
73
  require 'aerospike/cdt/map_order'
68
74
  require 'aerospike/cdt/map_return_type'
75
+ require 'aerospike/cdt/map_write_flags'
69
76
  require 'aerospike/cdt/map_write_mode'
70
77
  require 'aerospike/cdt/map_policy'
71
78
  require 'aerospike/geo_json'
@@ -1,12 +1,15 @@
1
- # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2016-2018 Aerospike, Inc.
3
4
  #
4
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
6
  # license agreements.
6
7
  #
7
8
  # Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
9
  # 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
+ # the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
10
13
  #
11
14
  # Unless required by applicable law or agreed to in writing, software
12
15
  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -36,33 +39,70 @@ module Aerospike
36
39
  # range is partially out of bounds, the valid part of the range will be
37
40
  # returned.
38
41
 
39
- class ListOperation
40
-
41
- APPEND = 1
42
- APPEND_ITEMS = 2
43
- INSERT = 3
44
- INSERT_ITEMS = 4
45
- POP = 5
46
- POP_RANGE = 6
47
- REMOVE = 7
48
- REMOVE_RANGE = 8
49
- SET = 9
50
- TRIM = 10
51
- CLEAR = 11
52
- INCREMENT = 12
53
- SIZE = 16
54
- GET = 17
55
- GET_RANGE = 18
42
+ class ListOperation < Operation
43
+
44
+ SET_TYPE = 0
45
+ APPEND = 1
46
+ APPEND_ITEMS = 2
47
+ INSERT = 3
48
+ INSERT_ITEMS = 4
49
+ POP = 5
50
+ POP_RANGE = 6
51
+ REMOVE = 7
52
+ REMOVE_RANGE = 8
53
+ SET = 9
54
+ TRIM = 10
55
+ CLEAR = 11
56
+ INCREMENT = 12
57
+ SORT = 13
58
+ SIZE = 16
59
+ GET = 17
60
+ GET_RANGE = 18
61
+ GET_BY_INDEX = 19
62
+ GET_BY_RANK = 21
63
+ GET_BY_VALUE = 22
64
+ GET_BY_VALUE_LIST = 23
65
+ GET_BY_INDEX_RANGE = 24
66
+ GET_BY_VALUE_INTERVAL = 25
67
+ GET_BY_RANK_RANGE = 26
68
+ GET_BY_VALUE_REL_RANK_RANGE = 27
69
+ REMOVE_BY_INDEX = 32
70
+ REMOVE_BY_RANK = 34
71
+ REMOVE_BY_VALUE = 35
72
+ REMOVE_BY_VALUE_LIST = 36
73
+ REMOVE_BY_INDEX_RANGE = 37
74
+ REMOVE_BY_VALUE_INTERVAL = 38
75
+ REMOVE_BY_RANK_RANGE = 39
76
+ REMOVE_BY_VALUE_REL_RANK_RANGE = 40
77
+
78
+ attr_reader :list_op, :arguments, :policy, :return_type
79
+
80
+ def initialize(op_type, list_op, bin_name, *arguments, return_type: nil)
81
+ @op_type = op_type
82
+ @bin_name = bin_name
83
+ @bin_value = nil
84
+ @list_op = list_op
85
+ @arguments = arguments
86
+ @return_type = return_type
87
+ end
88
+
89
+ ##
90
+ # Create a set list order operation.
91
+ # Server sets list order.
92
+ # Server returns null.
93
+ def self.set_order(bin_name, order)
94
+ ListOperation.new(Operation::CDT_MODIFY, SET_TYPE, bin_name, order)
95
+ end
56
96
 
57
97
  ##
58
98
  # Create list append operation.
59
99
  # Server appends value(s) to end of the list bin.
60
100
  # Server returns list size.
61
- def self.append(bin_name, *values)
101
+ def self.append(bin_name, *values, policy: ListPolicy::DEFAULT)
62
102
  if values.length > 1
63
- create_operation(Operation::CDT_MODIFY, APPEND_ITEMS, bin_name, values)
103
+ ListOperation.new(Operation::CDT_MODIFY, APPEND_ITEMS, bin_name, values, policy.order, policy.flags)
64
104
  else
65
- create_operation(Operation::CDT_MODIFY, APPEND, bin_name, values.first)
105
+ ListOperation.new(Operation::CDT_MODIFY, APPEND, bin_name, values.first, policy.order, policy.flags)
66
106
  end
67
107
  end
68
108
 
@@ -70,11 +110,11 @@ module Aerospike
70
110
  # Create list insert operation.
71
111
  # Server inserts value(s) at the specified index of the list bin.
72
112
  # Server returns list size.
73
- def self.insert(bin_name, index, *values)
113
+ def self.insert(bin_name, index, *values, policy: ListPolicy::DEFAULT)
74
114
  if values.length > 1
75
- create_operation(Operation::CDT_MODIFY, INSERT_ITEMS, bin_name, index, values)
115
+ ListOperation.new(Operation::CDT_MODIFY, INSERT_ITEMS, bin_name, index, values, policy.flags)
76
116
  else
77
- create_operation(Operation::CDT_MODIFY, INSERT, bin_name, index, values.first)
117
+ ListOperation.new(Operation::CDT_MODIFY, INSERT, bin_name, index, values.first, policy.flags)
78
118
  end
79
119
  end
80
120
 
@@ -82,7 +122,7 @@ module Aerospike
82
122
  # Create list pop operation.
83
123
  # Server returns item at specified index and removes item from list bin.
84
124
  def self.pop(bin_name, index)
85
- create_operation(Operation::CDT_MODIFY, POP, bin_name, index)
125
+ ListOperation.new(Operation::CDT_MODIFY, POP, bin_name, index)
86
126
  end
87
127
 
88
128
  ##
@@ -93,9 +133,9 @@ module Aerospike
93
133
  # removes those items from the list bin.
94
134
  def self.pop_range(bin_name, index, count=nil)
95
135
  if count
96
- create_operation(Operation::CDT_MODIFY, POP_RANGE, bin_name, index, count)
136
+ ListOperation.new(Operation::CDT_MODIFY, POP_RANGE, bin_name, index, count)
97
137
  else
98
- create_operation(Operation::CDT_MODIFY, POP_RANGE, bin_name, index)
138
+ ListOperation.new(Operation::CDT_MODIFY, POP_RANGE, bin_name, index)
99
139
  end
100
140
  end
101
141
 
@@ -104,7 +144,7 @@ module Aerospike
104
144
  # Server removes item at specified index from list bin.
105
145
  # Server returns number of items removed.
106
146
  def self.remove(bin_name, index)
107
- create_operation(Operation::CDT_MODIFY, REMOVE, bin_name, index)
147
+ ListOperation.new(Operation::CDT_MODIFY, REMOVE, bin_name, index)
108
148
  end
109
149
 
110
150
  ##
@@ -115,9 +155,9 @@ module Aerospike
115
155
  # Server returns number of items removed.
116
156
  def self.remove_range(bin_name, index, count=nil)
117
157
  if count
118
- create_operation(Operation::CDT_MODIFY, REMOVE_RANGE, bin_name, index, count)
158
+ ListOperation.new(Operation::CDT_MODIFY, REMOVE_RANGE, bin_name, index, count)
119
159
  else
120
- create_operation(Operation::CDT_MODIFY, REMOVE_RANGE, bin_name, index)
160
+ ListOperation.new(Operation::CDT_MODIFY, REMOVE_RANGE, bin_name, index)
121
161
  end
122
162
  end
123
163
 
@@ -125,22 +165,19 @@ module Aerospike
125
165
  # Create list set operation.
126
166
  # Server sets item value at specified index in list bin.
127
167
  # Server does not return a result by default.
128
- def self.set(bin_name, index, value)
129
- create_operation(Operation::CDT_MODIFY, SET, bin_name, index, value)
168
+ def self.set(bin_name, index, value, policy: ListPolicy::DEFAULT)
169
+ ListOperation.new(Operation::CDT_MODIFY, SET, bin_name, index, value, policy.flags)
130
170
  end
131
171
 
132
172
  ##
133
173
  # Create list trim operation.
174
+ #
134
175
  # Server removes items in list bin that do not fall into range specified
135
- # by index and count. If count is not specified, server will keep all
136
- # items starting at the specified index to the end of the list.
176
+ # by index and count.
177
+ #
137
178
  # Server returns number of items removed.
138
- def self.trim(bin_name, index, count=nil)
139
- if count
140
- create_operation(Operation::CDT_MODIFY, TRIM, bin_name, index, count)
141
- else
142
- create_operation(Operation::CDT_MODIFY, TRIM, bin_name, index)
143
- end
179
+ def self.trim(bin_name, index, count)
180
+ ListOperation.new(Operation::CDT_MODIFY, TRIM, bin_name, index, count)
144
181
  end
145
182
 
146
183
  ##
@@ -148,33 +185,37 @@ module Aerospike
148
185
  # Server removes all items in the list bin.
149
186
  # Server does not return a result by default.
150
187
  def self.clear(bin_name)
151
- create_operation(Operation::CDT_MODIFY, CLEAR, bin_name)
188
+ ListOperation.new(Operation::CDT_MODIFY, CLEAR, bin_name)
152
189
  end
153
190
 
154
191
  ##
155
192
  # Create list increment operation.
156
193
  # Server increments list[index] by value. If not specified, value defaults to 1.
157
194
  # Server returns the value of list[index] after the operation.
158
- def self.increment(bin_name, index, value = nil)
159
- if value
160
- create_operation(Operation::CDT_MODIFY, INCREMENT, bin_name, index, value)
161
- else
162
- create_operation(Operation::CDT_MODIFY, INCREMENT, bin_name, index)
163
- end
195
+ def self.increment(bin_name, index, value = 1, policy: ListPolicy::DEFAULT)
196
+ ListOperation.new(Operation::CDT_MODIFY, INCREMENT, bin_name, index, value, policy.order, policy.flags)
197
+ end
198
+
199
+ ##
200
+ # Create list sort operation.
201
+ # Server sorts list according to sort_flags.
202
+ # Server does not return a result by default.
203
+ def self.sort(bin_name, sort_flags = ListSortFlags::DEFAULT)
204
+ ListOperation.new(Operation::CDT_MODIFY, SORT, bin_name, sort_flags)
164
205
  end
165
206
 
166
207
  ##
167
208
  # Create list size operation.
168
209
  # Server returns size of list.
169
210
  def self.size(bin_name)
170
- create_operation(Operation::CDT_READ, SIZE, bin_name)
211
+ ListOperation.new(Operation::CDT_READ, SIZE, bin_name)
171
212
  end
172
213
 
173
214
  ##
174
215
  # Create list get operation.
175
216
  # Server returns the item at the specified index in the list bin.
176
217
  def self.get(bin_name, index)
177
- create_operation(Operation::CDT_READ, GET, bin_name, index)
218
+ ListOperation.new(Operation::CDT_READ, GET, bin_name, index)
178
219
  end
179
220
 
180
221
  ##
@@ -184,18 +225,270 @@ module Aerospike
184
225
  # starting at the specified index to the end of the list.
185
226
  def self.get_range(bin_name, index, count=nil)
186
227
  if count
187
- create_operation(Operation::CDT_READ, GET_RANGE, bin_name, index, count)
228
+ ListOperation.new(Operation::CDT_READ, GET_RANGE, bin_name, index, count)
229
+ else
230
+ ListOperation.new(Operation::CDT_READ, GET_RANGE, bin_name, index)
231
+ end
232
+ end
233
+
234
+ # Create list get by index operation.
235
+ #
236
+ # Server selects list item identified by index.
237
+ #
238
+ # Server returns selected data specified by return_type.
239
+ def self.get_by_index(bin_name, index, return_type: ListReturnType::NONE)
240
+ ListOperation.new(Operation::CDT_READ, GET_BY_INDEX, bin_name, index, return_type: return_type)
241
+ end
242
+
243
+ # Create list get by index range operation.
244
+ #
245
+ # Server selects list item identified by index range
246
+ #
247
+ # Server returns selected data specified by return_type.
248
+ def self.get_by_index_range(bin_name, index, count=nil, return_type: ListReturnType::NONE)
249
+ if count
250
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_INDEX_RANGE, bin_name, index, count, return_type: return_type)
251
+ else
252
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_INDEX_RANGE, bin_name, index, return_type: return_type)
253
+ end
254
+ end
255
+
256
+ # Create list get by rank operation.
257
+ #
258
+ # Server selects list item identified by rank.
259
+ #
260
+ # Server returns selected data specified by return_type.
261
+ def self.get_by_rank(bin_name, rank, return_type: ListReturnType::NONE)
262
+ ListOperation.new(Operation::CDT_READ, GET_BY_RANK, bin_name, rank, return_type: return_type)
263
+ end
264
+
265
+ # Create list get by rank range operation.
266
+ #
267
+ # Server selects list item identified by rank range.
268
+ #
269
+ # Server returns selected data specified by return_type.
270
+ def self.get_by_rank_range(bin_name, rank, count=nil, return_type: ListReturnType::NONE)
271
+ if count
272
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_RANK_RANGE, bin_name, rank, count, return_type: return_type)
273
+ else
274
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_RANK_RANGE, bin_name, rank, return_type: return_type)
275
+ end
276
+ end
277
+
278
+ # Create list get by value operation.
279
+ #
280
+ # Server selects list items identified by value.
281
+ #
282
+ # Server returns selected data specified by return_type.
283
+ def self.get_by_value(bin_name, value, return_type: ListReturnType::NONE)
284
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_VALUE, bin_name, value, return_type: return_type)
285
+ end
286
+
287
+ # Create list get by value range operation.
288
+ #
289
+ # Server selects list items identified by value range (value_begin
290
+ # inclusive, value_end exclusive). If value_begin is null, the range is
291
+ # less than value_end. If value_end is null, the range is greater than
292
+ # equal to value_begin.
293
+ #
294
+ # Server returns selected data specified by return_type.
295
+ def self.get_by_value_range(bin_name, value_begin, value_end = nil, return_type: ListReturnType::NONE)
296
+ if value_end
297
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_VALUE_INTERVAL, bin_name, value_begin, value_end, return_type: return_type)
298
+ else
299
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_VALUE_INTERVAL, bin_name, value_begin, return_type: return_type)
300
+ end
301
+ end
302
+
303
+ # Create list get by value list operation.
304
+ #
305
+ # Server selects list items identified by values.
306
+ #
307
+ # Server returns selected data specified by return_type.
308
+ def self.get_by_value_list(bin_name, values, return_type: ListReturnType::NONE)
309
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_VALUE_LIST, bin_name, values, return_type: return_type)
310
+ end
311
+
312
+ # Create list get by value relative to rank range list operation.
313
+ #
314
+ # Server selects list items nearest to value and greater, by relative
315
+ # rank with a count limit.
316
+ #
317
+ # Server returns selected data specified by return_type.
318
+ #
319
+ # Examples for ordered list [0, 4, 5, 9, 11, 15]:
320
+ # <ul>
321
+ # <li>(value, rank, count) = [selected items]</li>
322
+ # <li>(5, 0, 2) = [5, 9]</li>
323
+ # <li>(5, 1, 1) = [9]</li>
324
+ # <li>(5, -1, 2) = [4, 5]</li>
325
+ # <li>(3, 0, 1) = [4]</li>
326
+ # <li>(3, 3, 7) = [11, 15]</li>
327
+ # <li>(3, -3, 2) = []</li>
328
+ # </ul>
329
+ #
330
+ # Without count:
331
+ #
332
+ # Examples for ordered list [0, 4, 5, 9, 11, 15]:
333
+ # <ul>
334
+ # <li>(value, rank) = [selected items]</li>
335
+ # <li>(5, 0) = [5, 9, 11, 15]</li>
336
+ # <li>(5, 1) = [9, 11, 15]</li>
337
+ # <li>(5, -1) = [4, 5, 9, 11, 15]</li>
338
+ # <li>(3, 0) = [4, 5, 9, 11, 15]</li>
339
+ # <li>(3, 3) = [11, 15]</li>
340
+ # <li>(3, -3) = [0, 4, 5, 9, 11, 15]</li>
341
+ # </ul>
342
+ def self.get_by_value_rel_rank_range(bin_name, value, rank, count = nil, return_type: ListReturnType::NONE)
343
+ if count
344
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_VALUE_REL_RANK_RANGE, bin_name, value, rank, count, return_type: return_type)
345
+ else
346
+ InvertibleListOp.new(Operation::CDT_READ, GET_BY_VALUE_REL_RANK_RANGE, bin_name, value, rank, return_type: return_type)
347
+ end
348
+ end
349
+
350
+ # Create list remove by index operation.
351
+ #
352
+ # Server removes list item identified by index.
353
+ #
354
+ # Server returns selected data specified by return_type.
355
+ def self.remove_by_index(bin_name, index, return_type: ListReturnType::NONE)
356
+ ListOperation.new(Operation::CDT_MODIFY, REMOVE_BY_INDEX, bin_name, index, return_type: return_type)
357
+ end
358
+
359
+ # Create list remove by index range operation.
360
+ #
361
+ # Server removes list item identified by index range
362
+ #
363
+ # Server returns selected data specified by return_type.
364
+ def self.remove_by_index_range(bin_name, index, count=nil, return_type: ListReturnType::NONE)
365
+ if count
366
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_INDEX_RANGE, bin_name, index, count, return_type: return_type)
367
+ else
368
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_INDEX_RANGE, bin_name, index, return_type: return_type)
369
+ end
370
+ end
371
+
372
+ # Create list remove by rank operation.
373
+ #
374
+ # Server removes list item identified by rank.
375
+ #
376
+ # Server returns selected data specified by return_type.
377
+ def self.remove_by_rank(bin_name, rank, return_type: ListReturnType::NONE)
378
+ ListOperation.new(Operation::CDT_MODIFY, REMOVE_BY_RANK, bin_name, rank, return_type: return_type)
379
+ end
380
+
381
+ # Create list remove by rank range operation.
382
+ #
383
+ # Server removes list item identified by rank range.
384
+ #
385
+ # Server returns selected data specified by return_type.
386
+ def self.remove_by_rank_range(bin_name, rank, count=nil, return_type: ListReturnType::NONE)
387
+ if count
388
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_RANK_RANGE, bin_name, rank, count, return_type: return_type)
389
+ else
390
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_RANK_RANGE, bin_name, rank, return_type: return_type)
391
+ end
392
+ end
393
+
394
+ # Create list remove by value operation.
395
+ #
396
+ # Server removes list items identified by value.
397
+ #
398
+ # Server returns selected data specified by return_type.
399
+ def self.remove_by_value(bin_name, value, return_type: ListReturnType::NONE)
400
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_VALUE, bin_name, value, return_type: return_type)
401
+ end
402
+
403
+ # Create list remove by value range operation.
404
+ #
405
+ # Server removes list items identified by value range (value_begin
406
+ # inclusive, value_end exclusive). If value_begin is null, the range is
407
+ # less than value_end. If value_end is null, the range is greater than
408
+ # equal to value_begin.
409
+ #
410
+ # Server returns selected data specified by return_type.
411
+ def self.remove_by_value_range(bin_name, value_begin, value_end = nil, return_type: ListReturnType::NONE)
412
+ if value_end
413
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_VALUE_INTERVAL, bin_name, value_begin, value_end, return_type: return_type)
188
414
  else
189
- create_operation(Operation::CDT_READ, GET_RANGE, bin_name, index)
415
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_VALUE_INTERVAL, bin_name, value_begin, return_type: return_type)
190
416
  end
191
417
  end
192
418
 
419
+ # Create list remove by value list operation.
420
+ #
421
+ # Server removes list items identified by values.
422
+ #
423
+ # Server returns selected data specified by return_type.
424
+ def self.remove_by_value_list(bin_name, values, return_type: ListReturnType::NONE)
425
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_VALUE_LIST, bin_name, values, return_type: return_type)
426
+ end
427
+
428
+ # Create list remove by value relative to rank range list operation.
429
+ #
430
+ # Server removes list items nearest to value and greater, by relative
431
+ # rank with a count limit.
432
+ #
433
+ # Server returns selected data specified by return_type.
434
+ #
435
+ # Examples for ordered list [0, 4, 5, 9, 11, 15]:
436
+ # <ul>
437
+ # <li>(value, rank, count) = [selected items]</li>
438
+ # <li>(5, 0, 2) = [5, 9]</li>
439
+ # <li>(5, 1, 1) = [9]</li>
440
+ # <li>(5, -1, 2) = [4, 5]</li>
441
+ # <li>(3, 0, 1) = [4]</li>
442
+ # <li>(3, 3, 7) = [11, 15]</li>
443
+ # <li>(3, -3, 2) = []</li>
444
+ # </ul>
445
+ #
446
+ # Without count:
447
+ #
448
+ # Examples for ordered list [0, 4, 5, 9, 11, 15]:
449
+ # <ul>
450
+ # <li>(value, rank) = [selected items]</li>
451
+ # <li>(5, 0) = [5, 9, 11, 15]</li>
452
+ # <li>(5, 1) = [9, 11, 15]</li>
453
+ # <li>(5, -1) = [4, 5, 9, 11, 15]</li>
454
+ # <li>(3, 0) = [4, 5, 9, 11, 15]</li>
455
+ # <li>(3, 3) = [11, 15]</li>
456
+ # <li>(3, -3) = [0, 4, 5, 9, 11, 15]</li>
457
+ # </ul>
458
+ def self.remove_by_value_rel_rank_range(bin_name, value, rank, count = nil, return_type: ListReturnType::NONE)
459
+ if count
460
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_VALUE_REL_RANK_RANGE, bin_name, value, rank, count, return_type: return_type)
461
+ else
462
+ InvertibleListOp.new(Operation::CDT_MODIFY, REMOVE_BY_VALUE_REL_RANK_RANGE, bin_name, value, rank, return_type: return_type)
463
+ end
464
+ end
465
+
466
+ def and_return(return_type)
467
+ @return_type = return_type
468
+ @bin_value = nil
469
+ self
470
+ end
471
+
472
+ def invert_selection?
473
+ false
474
+ end
475
+
476
+ def bin_value
477
+ @bin_value ||= pack_bin_value
478
+ end
479
+
193
480
  private
194
481
 
195
- def self.create_operation(type, cdt_type, bin, *args)
482
+ def pack_bin_value
196
483
  bytes = nil
197
484
  Packer.use do |packer|
198
- packer.write_raw_short(cdt_type)
485
+ packer.write_raw_short(list_op)
486
+ args = arguments.dup
487
+ if return_type
488
+ rt = return_type
489
+ rt |= ListReturnType::INVERTED if invert_selection?
490
+ args.unshift(rt)
491
+ end
199
492
  if args.length > 0
200
493
  packer.write_array_header(args.length)
201
494
  args.each do |value|
@@ -204,7 +497,30 @@ module Aerospike
204
497
  end
205
498
  bytes = packer.bytes
206
499
  end
207
- return Operation.new(type, bin, BytesValue.new(bytes))
500
+ BytesValue.new(bytes)
501
+ end
502
+ end
503
+
504
+ class InvertibleListOp < ListOperation
505
+
506
+ ##
507
+ # Invert meaning of list command and return value.
508
+ #
509
+ # For example:
510
+ #
511
+ # ListOperation.remove_by_index_range(binName, index, count)
512
+ # .and_return(ListReturnType::VALUE)
513
+ # .invert_selection
514
+ #
515
+ # When calling invert_selection() on the list operation, the items
516
+ # outside the specified range will be removed and returned.
517
+ def invert_selection
518
+ @invert_selection = !@invert_selection
519
+ self
520
+ end
521
+
522
+ def invert_selection?
523
+ !!@invert_selection
208
524
  end
209
525
 
210
526
  end