aerospike 2.24.0 → 2.26.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 +27 -0
- data/lib/aerospike/cdt/context.rb +136 -69
- data/lib/aerospike/cdt/map_policy.rb +16 -2
- data/lib/aerospike/cdt/map_return_type.rb +9 -1
- data/lib/aerospike/client.rb +30 -32
- data/lib/aerospike/command/command.rb +104 -98
- data/lib/aerospike/command/operate_args.rb +99 -0
- data/lib/aerospike/command/operate_command.rb +6 -11
- data/lib/aerospike/exp/exp.rb +401 -334
- data/lib/aerospike/exp/exp_bit.rb +388 -0
- data/lib/aerospike/exp/exp_hll.rb +169 -0
- data/lib/aerospike/exp/exp_list.rb +403 -0
- data/lib/aerospike/exp/exp_map.rb +493 -0
- data/lib/aerospike/exp/operation.rb +56 -0
- data/lib/aerospike/features.rb +13 -0
- data/lib/aerospike/operation.rb +20 -22
- data/lib/aerospike/policy/policy.rb +25 -12
- data/lib/aerospike/query/filter.rb +44 -32
- data/lib/aerospike/query/query_executor.rb +7 -9
- data/lib/aerospike/query/query_partition_command.rb +32 -31
- data/lib/aerospike/query/recordset.rb +9 -9
- data/lib/aerospike/query/scan_executor.rb +7 -5
- data/lib/aerospike/task/execute_task.rb +17 -14
- data/lib/aerospike/utils/buffer.rb +46 -38
- data/lib/aerospike/utils/packer.rb +7 -6
- data/lib/aerospike/value/value.rb +21 -51
- data/lib/aerospike/version.rb +1 -1
- data/lib/aerospike.rb +156 -148
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 569388197af73988d3965e15f8b7caf42605896f21183a0e6f7d507690dec816
|
4
|
+
data.tar.gz: dfe35172403817d176aecfd83747e6155a961b92960a97f8efc713a6b7540d23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4de68155586c168c75a51c71749531becdf066cb22888745f8473237cb775dd9054c6401e44a04b00bee517848859d128141692da3fc7c970df2f202e5e49b9
|
7
|
+
data.tar.gz: 7c041a196f2bf45a3ff575426b9269ba45c10e16f641c82f5ce11e362ace013d2480c407b8f1e9a663a27bcf78df1988d6af46de2bd22d41c0fce5366fb2a52c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,33 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [2.26.0] 2022-12-02
|
6
|
+
|
7
|
+
- **New Features**
|
8
|
+
- [CLIENT-1808] Support creating a secondary index on elements within a CDT using `Context`.
|
9
|
+
- [CLIENT-1991] Add base64 encoding methods to `Context`.
|
10
|
+
- [CLIENT-2007] Support using `Context` in query filters.
|
11
|
+
|
12
|
+
## [2.25.0] 2022-11-28
|
13
|
+
|
14
|
+
- **New Features**
|
15
|
+
|
16
|
+
- [CLIENT-1984] Support scan-show and query-show info commands.
|
17
|
+
|
18
|
+
- [CLIENT-1362] Adds support Aerospike Expression filters. Expression filters are now supported on all commands, including `Client#get`, `Client#put`, `Client#delete`, `Client#operate`, `Client#scan`, `Client#query`, `Client#execute_udf`, etc.
|
19
|
+
|
20
|
+
- Adds `Policy#filter_exp` and `Policy#fail_on_filtered_out`
|
21
|
+
|
22
|
+
- Bit expressions: `Exp::Bit::` `#resize`, `#insert`, `#remove`, `#set`, `#or`, `#xor`, `#and`, `#not`, `#lshift`, `#rshift`, `#add`, `#subtract`, `#set_int`, `#get`, `#count`, `#lscan`, `#rscan`, `#get_int`, `#pack_math`, `#pack_get_int`, `#add_write`, `#add_read`
|
23
|
+
|
24
|
+
- HLL Expressions: `Exp::HLL::` `#init`, `#add`, `#get_count`, `#get_union`, `#get_union_count`, `#get_intersect_count`, `#get_similarity`, `#describe`, `#may_contain`, `#add_write`, `#add_read`
|
25
|
+
|
26
|
+
- Map Expressions: `Exp::Map::` `#put`, `#put_items`, `#increment`, `#clear`, `#remove_by_key`, `#remove_by_key_list`, `#remove_by_key_range`, `#remove_by_key_relative_index_range`, `#remove_by_value`, `#remove_by_value_list`, `#remove_by_value_range`, `#remove_by_value_relative_rank_range`, `#remove_by_value_relative_rank_range`, `#remove_by_index`, `#remove_by_index_range`, `#remove_by_rank`, `#remove_by_rank_range`, `#size`, `#get_by_key`, `#get_by_key_range`, `#get_by_key_list`, `#get_by_key_relative_index_range`, `#get_by_key_relative_index_range`, `#get_by_value`, `#get_by_value_range`, `#get_by_value_list`, `#get_by_value_relative_rank_range`, `#get_by_index`, `#get_by_index_range`, `#get_by_rank`, `#get_by_rank_range`, `#add_write`, `#add_read`, `#get_value_type`
|
27
|
+
|
28
|
+
- List Expressions: `Exp::List::` `#append`, `#append_items`, `#insert`, `#insert_items`, `#increment`, `#set`, `#clear`, `#sort`, `#remove_by_value`, `#remove_by_value_list`, `#remove_by_value_range`, `#remove_by_value_relative_rank_range`, `#remove_by_index`, `#remove_by_index_range`, `#remove_by_rank`, `#remove_by_rank_range`, `#size`, `#get_by_value`, `#get_by_value_range`, `#get_by_value_list`, `#get_by_value_relative_rank_range`, `#get_by_index`, `#get_by_index_range`, `#get_by_index_range`, `#get_by_rank`, `#get_by_rank_range`, `#get_by_rank_range`, `#add_write`, `#add_read`, `#get_value_type`, `#pack_range_operation`
|
29
|
+
|
30
|
+
- Read and Write operations: `Exp::Operation::` `#write`, `#read`
|
31
|
+
|
5
32
|
## [2.24.0] 2022-11-15
|
6
33
|
|
7
34
|
- **New Features**
|
@@ -17,16 +17,17 @@
|
|
17
17
|
# License for the specific language governing permissions and limitations under
|
18
18
|
# the License.
|
19
19
|
|
20
|
+
require "base64"
|
21
|
+
|
20
22
|
module Aerospike
|
21
23
|
module CDT
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
##
|
26
|
+
# Nested CDT context. Identifies the location of nested list/map to apply the operation.
|
27
|
+
# for the current level.
|
28
|
+
# An array of CTX identifies location of the list/map on multiple
|
29
|
+
# levels on nesting.
|
28
30
|
class Context
|
29
|
-
|
30
31
|
attr_accessor :id, :value
|
31
32
|
|
32
33
|
def initialize(id, value)
|
@@ -37,64 +38,64 @@ module Aerospike
|
|
37
38
|
##
|
38
39
|
# Create list with given type at index offset, given an order and pad.
|
39
40
|
def self.list_index_create(index, order, pad)
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
41
|
+
Context.new(0x10 | ListOrder.flag(order, pad), index)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Lookup list by index offset.
|
46
|
+
# If the index is negative, the resolved index starts backwards from end of list.
|
47
|
+
# If an index is out of bounds, a parameter error will be returned.
|
48
|
+
# Examples:
|
49
|
+
# 0: First item.
|
50
|
+
# 4: Fifth item.
|
51
|
+
# -1: Last item.
|
52
|
+
# -3: Third to last item.
|
53
|
+
def self.list_index(index)
|
54
|
+
Context.new(0x10, index)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Lookup list by rank.
|
59
|
+
# 0 = smallest value
|
60
|
+
# N = Nth smallest value
|
61
|
+
# -1 = largest value
|
62
|
+
def self.list_rank(rank)
|
63
|
+
Context.new(0x11, rank)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Lookup list by value.
|
68
|
+
def self.list_value(key)
|
69
|
+
Context.new(0x13, key)
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Lookup map by index offset.
|
74
|
+
# If the index is negative, the resolved index starts backwards from end of list.
|
75
|
+
# If an index is out of bounds, a parameter error will be returned.
|
76
|
+
# Examples:
|
77
|
+
# 0: First item.
|
78
|
+
# 4: Fifth item.
|
79
|
+
# -1: Last item.
|
80
|
+
# -3: Third to last item.
|
81
|
+
def self.map_index(index)
|
82
|
+
Context.new(0x20, index)
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Lookup map by rank.
|
87
|
+
# 0 = smallest value
|
88
|
+
# N = Nth smallest value
|
89
|
+
# -1 = largest value
|
90
|
+
def self.map_rank(rank)
|
91
|
+
Context.new(0x21, rank)
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Lookup map by key.
|
96
|
+
def self.map_key(key)
|
97
|
+
Context.new(0x22, key)
|
98
|
+
end
|
98
99
|
|
99
100
|
##
|
100
101
|
# Create map with given type at map key.
|
@@ -102,12 +103,78 @@ module Aerospike
|
|
102
103
|
Context.new(0x22 | order[:flag], key)
|
103
104
|
end
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
##
|
107
|
+
# Lookup map by value.
|
108
|
+
def self.map_value(key)
|
109
|
+
Context.new(0x23, key)
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Encodes the context via message pack.
|
114
|
+
def self.pack(packer, ctx)
|
115
|
+
unless ctx.to_a.empty?
|
116
|
+
packer.write_array_header(2)
|
117
|
+
ctx.each do |c|
|
118
|
+
packer.write(c.id)
|
119
|
+
Value.of(c.value)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Encodes the context via message pack and return the results.
|
126
|
+
def self.bytes(ctx)
|
127
|
+
unless ctx.to_a.empty?
|
128
|
+
Packer.use do |packer|
|
129
|
+
packer.write_array_header(ctx.length * 2)
|
130
|
+
ctx.each do |c|
|
131
|
+
packer.write(c.id)
|
132
|
+
Value.of(c.value).pack(packer)
|
133
|
+
end
|
134
|
+
return packer.bytes
|
135
|
+
end
|
136
|
+
end
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def ==(other)
|
141
|
+
self.id == other.id && self.value == other.value
|
142
|
+
end
|
110
143
|
|
144
|
+
##
|
145
|
+
# decodes the base64 encoded messagepack byte array
|
146
|
+
# and converts it to an array of Context.
|
147
|
+
def self.from_bytes(buf)
|
148
|
+
list = nil
|
149
|
+
Unpacker.use do |unpacker|
|
150
|
+
list = unpacker.unpack(buf)
|
151
|
+
end
|
152
|
+
|
153
|
+
unless list.length % 2 == 0
|
154
|
+
raise Exceptions::Aerospike.new(Aerospike::ResultCode::PARAMETER_ERROR, "Invalid buffer")
|
155
|
+
end
|
156
|
+
|
157
|
+
list.each_slice(2).map { |id, value| Context.new(id, value) }
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Encodes the context array to messagepack and then encodes
|
162
|
+
# the resulting byte array to base64.
|
163
|
+
def self.base64(ctx)
|
164
|
+
unless ctx.to_a.empty?
|
165
|
+
data = self.bytes(ctx)
|
166
|
+
return Base64.strict_encode64(data).force_encoding("binary")
|
167
|
+
end
|
168
|
+
""
|
169
|
+
end
|
170
|
+
|
171
|
+
##
|
172
|
+
# Decodes the byte array to messagepack and then decodes
|
173
|
+
# the resulting byte array to an array of Context.
|
174
|
+
def self.from_base64(buf)
|
175
|
+
bytes = Base64.strict_decode64(buf)
|
176
|
+
self.from_bytes(bytes)
|
177
|
+
end
|
111
178
|
end
|
112
179
|
end
|
113
180
|
end
|
@@ -17,8 +17,8 @@
|
|
17
17
|
module Aerospike
|
18
18
|
module CDT
|
19
19
|
class MapPolicy
|
20
|
-
|
21
20
|
attr_accessor :order, :write_mode, :flags
|
21
|
+
attr_accessor :item_command, :items_command, :attributes
|
22
22
|
|
23
23
|
def initialize(order: nil, write_mode: nil, flags: nil)
|
24
24
|
if write_mode && flags
|
@@ -28,10 +28,24 @@ module Aerospike
|
|
28
28
|
@order = order || MapOrder::DEFAULT
|
29
29
|
@write_mode = write_mode || MapWriteMode::DEFAULT
|
30
30
|
@flags = flags || MapWriteFlags::DEFAULT
|
31
|
+
@attributes = order ? order[:attr] : 0
|
32
|
+
|
33
|
+
case @write_mode
|
34
|
+
when CDT::MapWriteMode::DEFAULT
|
35
|
+
@item_command = CDT::MapOperation::PUT
|
36
|
+
@items_command = CDT::MapOperation::PUT_ITEMS
|
37
|
+
when CDT::MapWriteMode::UPDATE_ONLY
|
38
|
+
@item_command = CDT::MapOperation::REPLACE
|
39
|
+
@items_command = CDT::MapOperation::REPLACE_ITEMS
|
40
|
+
when CDT::MapWriteMode::CREATE_ONLY
|
41
|
+
@item_command = CDT::MapOperation::ADD
|
42
|
+
@items_command = CDT::MapOperation::ADD_ITEMS
|
43
|
+
else
|
44
|
+
raise Exceptions.new(ResultCode::PARAMETER_ERROR, "invalid value for MapWriteMode #{write_mode}")
|
45
|
+
end
|
31
46
|
end
|
32
47
|
|
33
48
|
DEFAULT = MapPolicy.new
|
34
|
-
|
35
49
|
end
|
36
50
|
end
|
37
51
|
end
|
@@ -69,10 +69,18 @@ module Aerospike
|
|
69
69
|
# Return true if count > 0.
|
70
70
|
EXISTS = 13
|
71
71
|
|
72
|
+
##
|
73
|
+
# :private
|
74
|
+
#
|
75
|
+
# TODO: Should be like ListOperation and Implement InvertibleMapOperation
|
76
|
+
# Inverts meaning of map command and return values. For example:
|
77
|
+
# map_remove_by_key_range(bin_name, key_begin, key_end, MapReturnType::KEY | MapReturnType::INVERTED)
|
78
|
+
# With the INVERTED flag enabled, the keys outside of the specified key range will be removed and returned.
|
79
|
+
INVERTED = 0x10000
|
80
|
+
|
72
81
|
##
|
73
82
|
# Default return type: NONE
|
74
83
|
DEFAULT_RETURN_TYPE = NONE
|
75
|
-
|
76
84
|
end
|
77
85
|
end
|
78
86
|
end
|
data/lib/aerospike/client.rb
CHANGED
@@ -15,8 +15,8 @@
|
|
15
15
|
# License for the specific language governing permissions and limitations under
|
16
16
|
# the License.
|
17
17
|
|
18
|
-
require
|
19
|
-
require
|
18
|
+
require "digest"
|
19
|
+
require "base64"
|
20
20
|
|
21
21
|
module Aerospike
|
22
22
|
|
@@ -36,7 +36,6 @@ module Aerospike
|
|
36
36
|
# +:fail_if_not_connected+ set to true
|
37
37
|
|
38
38
|
class Client
|
39
|
-
|
40
39
|
attr_accessor :default_admin_policy
|
41
40
|
attr_accessor :default_batch_policy
|
42
41
|
attr_accessor :default_info_policy
|
@@ -48,8 +47,7 @@ module Aerospike
|
|
48
47
|
attr_accessor :cluster
|
49
48
|
|
50
49
|
def initialize(hosts = nil, policy: ClientPolicy.new, connect: true)
|
51
|
-
|
52
|
-
hosts = ::Aerospike::Host::Parse.(hosts || ENV['AEROSPIKE_HOSTS'] || 'localhost')
|
50
|
+
hosts = ::Aerospike::Host::Parse.(hosts || ENV["AEROSPIKE_HOSTS"] || "localhost")
|
53
51
|
policy = create_policy(policy, ClientPolicy)
|
54
52
|
set_default_policies(policy.policies)
|
55
53
|
@cluster = Cluster.new(policy, hosts)
|
@@ -249,7 +247,7 @@ module Aerospike
|
|
249
247
|
end
|
250
248
|
|
251
249
|
response = send_info_command(policy, str_cmd, node).upcase
|
252
|
-
return if response ==
|
250
|
+
return if response == "OK"
|
253
251
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_ERROR, "Truncate failed: #{response}")
|
254
252
|
end
|
255
253
|
|
@@ -386,7 +384,8 @@ module Aerospike
|
|
386
384
|
def operate(key, operations, options = nil)
|
387
385
|
policy = create_policy(options, OperatePolicy, default_operate_policy)
|
388
386
|
|
389
|
-
|
387
|
+
args = OperateArgs.new(cluster, policy, default_write_policy, default_operate_policy, key, operations)
|
388
|
+
command = OperateCommand.new(@cluster, key, args)
|
390
389
|
execute_command(command)
|
391
390
|
command.record
|
392
391
|
end
|
@@ -415,7 +414,7 @@ module Aerospike
|
|
415
414
|
def register_udf(udf_body, server_path, language, options = nil)
|
416
415
|
policy = create_policy(options, Policy, default_info_policy)
|
417
416
|
|
418
|
-
content = Base64.strict_encode64(udf_body).force_encoding(
|
417
|
+
content = Base64.strict_encode64(udf_body).force_encoding("binary")
|
419
418
|
str_cmd = "udf-put:filename=#{server_path};content=#{content};"
|
420
419
|
str_cmd << "content-len=#{content.length};udf-type=#{language};"
|
421
420
|
|
@@ -424,15 +423,15 @@ module Aerospike
|
|
424
423
|
|
425
424
|
res = {}
|
426
425
|
response_map.each do |k, response|
|
427
|
-
vals = response.to_s.split(
|
426
|
+
vals = response.to_s.split(";")
|
428
427
|
vals.each do |pair|
|
429
428
|
k, v = pair.split("=", 2)
|
430
429
|
res[k] = v
|
431
430
|
end
|
432
431
|
end
|
433
432
|
|
434
|
-
if res[
|
435
|
-
raise Aerospike::Exceptions::CommandRejected.new("Registration failed: #{res[
|
433
|
+
if res["error"]
|
434
|
+
raise Aerospike::Exceptions::CommandRejected.new("Registration failed: #{res["error"]}\nFile: #{res["file"]}\nLine: #{res["line"]}\nMessage: #{res["message"]}")
|
436
435
|
end
|
437
436
|
|
438
437
|
UdfRegisterTask.new(@cluster, server_path)
|
@@ -454,7 +453,7 @@ module Aerospike
|
|
454
453
|
response_map = @cluster.request_info(policy, str_cmd)
|
455
454
|
_, response = response_map.first
|
456
455
|
|
457
|
-
if response ==
|
456
|
+
if response == "ok"
|
458
457
|
UdfRemoveTask.new(@cluster, udf_name)
|
459
458
|
else
|
460
459
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_ERROR, response)
|
@@ -466,27 +465,27 @@ module Aerospike
|
|
466
465
|
def list_udf(options = nil)
|
467
466
|
policy = create_policy(options, Policy, default_info_policy)
|
468
467
|
|
469
|
-
str_cmd =
|
468
|
+
str_cmd = "udf-list"
|
470
469
|
|
471
470
|
# Send command to one node. That node will distribute it to other nodes.
|
472
471
|
response_map = @cluster.request_info(policy, str_cmd)
|
473
472
|
_, response = response_map.first
|
474
473
|
|
475
|
-
vals = response.split(
|
474
|
+
vals = response.split(";")
|
476
475
|
|
477
476
|
vals.map do |udf_info|
|
478
|
-
next if udf_info.strip! ==
|
477
|
+
next if udf_info.strip! == ""
|
479
478
|
|
480
|
-
udf_parts = udf_info.split(
|
479
|
+
udf_parts = udf_info.split(",")
|
481
480
|
udf = UDF.new
|
482
481
|
udf_parts.each do |values|
|
483
|
-
k, v = values.split(
|
482
|
+
k, v = values.split("=", 2)
|
484
483
|
case k
|
485
|
-
when
|
484
|
+
when "filename"
|
486
485
|
udf.filename = v
|
487
|
-
when
|
486
|
+
when "hash"
|
488
487
|
udf.hash = v
|
489
|
-
when
|
488
|
+
when "type"
|
490
489
|
udf.language = v
|
491
490
|
end
|
492
491
|
end
|
@@ -501,7 +500,7 @@ module Aerospike
|
|
501
500
|
# udf file = <server udf dir>/<package name>.lua
|
502
501
|
#
|
503
502
|
# This method is only supported by Aerospike 3 servers.
|
504
|
-
def execute_udf(key, package_name, function_name, args=[], options = nil)
|
503
|
+
def execute_udf(key, package_name, function_name, args = [], options = nil)
|
505
504
|
policy = create_policy(options, WritePolicy, default_write_policy)
|
506
505
|
|
507
506
|
command = ExecuteCommand.new(@cluster, policy, key, package_name, function_name, args)
|
@@ -514,10 +513,10 @@ module Aerospike
|
|
514
513
|
result_map = record.bins
|
515
514
|
|
516
515
|
# User defined functions don't have to return a value.
|
517
|
-
key, obj = result_map.detect{ |k, _| k.include?(
|
516
|
+
key, obj = result_map.detect { |k, _| k.include?("SUCCESS") }
|
518
517
|
return obj if key
|
519
518
|
|
520
|
-
key, obj = result_map.detect{ |k, _| k.include?(
|
519
|
+
key, obj = result_map.detect { |k, _| k.include?("FAILURE") }
|
521
520
|
message = key ? obj.to_s : "Invalid UDF return value"
|
522
521
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::UDF_BAD_RESPONSE, message)
|
523
522
|
end
|
@@ -530,7 +529,7 @@ module Aerospike
|
|
530
529
|
#
|
531
530
|
# This method is only supported by Aerospike 3 servers.
|
532
531
|
# If the policy is nil, the default relevant policy will be used.
|
533
|
-
def execute_udf_on_query(statement, package_name, function_name, function_args=[], options = nil)
|
532
|
+
def execute_udf_on_query(statement, package_name, function_name, function_args = [], options = nil)
|
534
533
|
policy = create_policy(options, QueryPolicy, default_query_policy)
|
535
534
|
|
536
535
|
nodes = @cluster.nodes
|
@@ -559,7 +558,6 @@ module Aerospike
|
|
559
558
|
ExecuteTask.new(@cluster, statement)
|
560
559
|
end
|
561
560
|
|
562
|
-
|
563
561
|
# Create secondary index.
|
564
562
|
# This asynchronous server call will return before command is complete.
|
565
563
|
# The user can optionally wait for command completion by using the returned
|
@@ -568,7 +566,8 @@ module Aerospike
|
|
568
566
|
# This method is only supported by Aerospike 3 servers.
|
569
567
|
# index_type should be :string, :numeric or :geo2dsphere (requires server version 3.7 or later)
|
570
568
|
# collection_type should be :list, :mapkeys or :mapvalues
|
571
|
-
|
569
|
+
# ctx is an optional list of context. Supported on server v6.1+.
|
570
|
+
def create_index(namespace, set_name, index_name, bin_name, index_type, collection_type = nil, options = nil, ctx: nil)
|
572
571
|
if options.nil? && collection_type.is_a?(Hash)
|
573
572
|
options, collection_type = collection_type, nil
|
574
573
|
end
|
@@ -577,18 +576,19 @@ module Aerospike
|
|
577
576
|
str_cmd = "sindex-create:ns=#{namespace}"
|
578
577
|
str_cmd << ";set=#{set_name}" unless set_name.to_s.strip.empty?
|
579
578
|
str_cmd << ";indexname=#{index_name};numbins=1"
|
579
|
+
str_cmd << ";context=#{CDT::Context.base64(ctx)}" unless ctx.to_a.empty?
|
580
580
|
str_cmd << ";indextype=#{collection_type.to_s.upcase}" if collection_type
|
581
581
|
str_cmd << ";indexdata=#{bin_name},#{index_type.to_s.upcase}"
|
582
582
|
str_cmd << ";priority=normal"
|
583
583
|
|
584
584
|
# Send index command to one node. That node will distribute the command to other nodes.
|
585
585
|
response = send_info_command(policy, str_cmd).upcase
|
586
|
-
if response ==
|
586
|
+
if response == "OK"
|
587
587
|
# Return task that could optionally be polled for completion.
|
588
588
|
return IndexTask.new(@cluster, namespace, index_name)
|
589
589
|
end
|
590
590
|
|
591
|
-
if response.start_with?(
|
591
|
+
if response.start_with?("FAIL:200")
|
592
592
|
# Index has already been created. Do not need to poll for completion.
|
593
593
|
return IndexTask.new(@cluster, namespace, index_name, true)
|
594
594
|
end
|
@@ -607,10 +607,10 @@ module Aerospike
|
|
607
607
|
|
608
608
|
# Send index command to one node. That node will distribute the command to other nodes.
|
609
609
|
response = send_info_command(policy, str_cmd).upcase
|
610
|
-
return if response ==
|
610
|
+
return if response == "OK"
|
611
611
|
|
612
612
|
# Index did not previously exist. Return without error.
|
613
|
-
return if response.start_with?(
|
613
|
+
return if response.start_with?("FAIL:201")
|
614
614
|
|
615
615
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INDEX_GENERIC, "Drop index failed: #{response}")
|
616
616
|
end
|
@@ -966,7 +966,5 @@ module Aerospike
|
|
966
966
|
|
967
967
|
threads.each(&:join)
|
968
968
|
end
|
969
|
-
|
970
969
|
end # class
|
971
|
-
|
972
970
|
end # module
|